1 var 2 WINDOW_APP = WINDOW_APP || {}; 3 4 WINDOW_APP.util = {}; 5 6 7 /** 8 * スクロールの監視 9 * 10 * @class 11 * @author ngi@phantom4.org 12 * @example 13 * 14 * /** 15 * * スクロールの監視イベント 16 * * 17 * * @param params {Object} 監視中のパラメーター 18 * * @param params.status {int} 0: スクロール停止した、1: スクロール開始した、2: スクロール中、-1: スクロールしていない 19 * * @param params.positionX {Number} 縦スクロールの位置 20 * * @param params.positionY {Number} 横スクロールの位置 21 * * @param params.deltaX {Number} 縦スクロールの移動量 22 * * @param params.deltaY {Number} 横スクロールの移動量 23 * *\/ 24 * function onScroll (params) { 25 * switch(params.status) { 26 * case 0: 27 * //スクロール停止したときの処理 28 * break; 29 * 30 * case 1: 31 * //スクロール開始したときの処理 32 * break; 33 * 34 * case 2: 35 * //スクロール中の処理 36 * break; 37 * } 38 * } 39 * 40 * WINDOW_APP.util.scrollMonitor.add(onScroll); //リスナー追加 41 */ 42 43 44 WINDOW_APP.util.scrollMonitor = (function () { 45 var 46 _DELAY = 100, 47 48 _isPlaying = false, //動作中か 49 _listeners = [], //リスナー 50 _numListener = 0, //追加された要素の数 51 _timer, //タイマー 52 _isScrolling = false, //スクロール中か 53 _prevPoint = { 54 x: 0, 55 y: 0 56 }; //前回のスクロール座標 57 58 /** 59 * イベントを追加する 60 * 61 * @param func {Function} リスナー 62 * @return {Boolean} 追加されたか 63 */ 64 function add (func) { 65 var 66 result = false, //結果 67 isAdded = false; //すでに追加されているか 68 69 if(typeof func === "function") { 70 //同じものがあれば上書き 71 for(var i = 0; i < _numListener; i++) { 72 if(_listeners[i] === func) { 73 _listeners[i] = func; 74 isAdded = true; 75 break; 76 } 77 } 78 79 if(!isAdded) { 80 _listeners.push(func); 81 _numListener++; 82 } 83 } 84 85 //動作開始 86 if(!_isPlaying && _numListener > 0) { 87 start(); 88 } 89 90 return result; 91 } 92 93 /** 94 * イベントを削除する 95 * 96 * @param func {Function} リスナー 97 * @return {Boolean} 削除されたか 98 */ 99 function remove (func) { 100 var result = false; 101 for(var i = 0; i < _numListener; i++) { 102 //一致したリスナーを削除 103 if(_listeners[i] === func) { 104 delete _listeners[i]; 105 _numListener--; 106 break; 107 } 108 } 109 110 //動作終了 111 if(_numListener <= 0) { 112 stop(); 113 } 114 115 return result; 116 } 117 118 /** 119 * モニターの開始(手動で実行する場合) 120 * 121 */ 122 function start () { 123 stop(); 124 _timer = setInterval(_monitor, _DELAY); 125 _isPlaying = true; 126 } 127 128 /** 129 * モニターの停止(手動で実行する場合) 130 * 131 */ 132 function stop () { 133 if(_timer) { 134 clearInterval(_timer); 135 } 136 _isPlaying = false; 137 } 138 139 /** 140 * 監視&通知 141 * 142 */ 143 function _monitor () { 144 var 145 top = document.documentElement.scrollTop || document.body.scrollTop, //スクロール上 146 left = document.documentElement.scrollLeft || document.body.scrollLeft, //スクロール左 147 isMove = false, //移動したか 148 status = -1; //スクロール開始、停止、スクロール中 149 150 if(_prevPoint.x != left) { 151 isMove = true; 152 } 153 154 if(_prevPoint.y != top) { 155 isMove = true; 156 } 157 158 //ステータスの設定 159 if(isMove && _isScrolling) { 160 status = 2; //スクロール中 161 } 162 else if (isMove && !_isScrolling) { 163 status = 1; //スクロール開始 164 } 165 else if (!isMove && _isScrolling) { 166 status = 0; //スクロール停止 167 } 168 169 //通知 170 for(var i = 0; i < _numListener; i++) { 171 _listeners[i].apply(window, [{ 172 status: status, 173 positionX: left, //x座標 174 positionY: top, //y座標 175 deltaX: left - _prevPoint.x, //x座標の移動量 176 deltaY: top - _prevPoint.y //y座標の移動量 177 }]); 178 } 179 180 _isScrolling = isMove; 181 _prevPoint.x = left; 182 _prevPoint.y = top; 183 } 184 185 186 return { 187 add: add, 188 remove: remove, 189 start: start, 190 stop: stop 191 }; 192 }());