注: 私は長い間 JavaScript を学習していませんでしたが、最近、Web 上のモバイル Web ページと WeChat アプリケーションに取り組んでいたので、touchstart イベントと touchend イベントを使用してそれらをシミュレートしました。元のプログラムをカプセル化しようとしています。次の 2 つの問題の解決策が得られました。みんなで共有して、マスターに指導を求めてください
モバイル Web アプリ開発では、クリック イベントの 300 ミリ秒の遅延により、特にローエンド マシンで応答が遅くなります。 touchstart イベントまたは touchend イベントを使用すると、デフォルトのホイール イベントと競合しますが、これは予想外です。
そこで、私は自分でそれを行い、十分な衣食住を用意し、クイッククリックイベント用のネイティブjsコードを書きました(Webアプリの開発環境を考慮すると、IEなどのブラウザとの互換性を考慮する必要はありません)。当面)。
実装方法1は以下の通りです:
function FastClickEvent(handler){ var fastclick = { handler : handler, bind : function(query){ var targetList = document.querySelectorAll(query); for(var i=0,len=targetList.length;i<len;i++) { targetList[i].addEventListener('touchstart',handleEvent); targetList[i].addEventListener('touchend',handleEvent); } }, unbind : function(query){ var targetList = document.querySelectorAll(query); for(var i=0,len=targetList.length;i<len;i++) { targetList[i].removeEventListener('touchstart',handleEvent); targetList[i].removeEventListener('touchend',handleEvent); } } } var touchX = 0 ,touchY = 0; function handleEvent(event){ switch(event.type) { case 'touchstart': touchX = event.touches[0].clientX; touchY = event.touches[0].clientY; break; case 'touchend': var x = event.changedTouches[0].clientX; var y = event.changedTouches[0].clientY; if(Math.abs(touchX-x)<5||Math.abs(touchY-y)<5) fastclick.handler(event); break; } }; return fastclick; };
原理:タッチスタートイベントとタッチエンドイベントが連続発生した時の位置の変化に基づいてクリックかどうかを判定します
Call:ハンドラー関数を使用してFastClickEventを登録しますイベント。次に、bind メソッドを使用して、登録された FastClickEvent イベントを対応する要素にバインドします。次のように:
var handler = function(event){ console.log(event.target.id+" fastclicked"); } var fastClick = new FastClickEvent(handler); fastClick.bind("div");
このコードでは、すべての div 要素に対して fastclick ハンドラー イベントを登録します。 fastClick.unbind を呼び出して要素のバインドを解除します。
しかし、handleEvent イベントが touchX、touchY にアクセスできるようにするには、このコードには問題があります。クロージャ メソッドを使用しました。これは、新しい FastClickEvent イベント オブジェクトが作成されるたびに、繰り返し handleEvent 関数をメモリに挿入する必要があることを意味します。 touchXとtouchYの繰り返しについては、言うまでもありません。
初心者向けヘルプ: 元々は handleEvent 関数をプロトタイプに書きたかったのですが、handleEvent (イベント) のこのオブジェクトが Windows であるという問題が発生します。つまり、touchX、touchY、およびハンドラーを取得できないということです。オブジェクトが存在し、アクセス エラーが発生します。
比較的単純な解決策があります。それは、fastClickEvent イベントを 1 つだけ登録し、event.target (つまり、イベントが発生するオブジェクト) の実際の値に基づいてハンドラー内の応答コンテンツを決定することです。
ただし、これは、すべての fastclick イベントに精通している必要があることを意味します。
このメソッドを使用する利点は、handleEvent 関数が 1 つしかないため、基本的に、fastclick イベントを再度トリガーしたくない場合を除き、ページがリリースされる前に、要素の fastclick イベントのバインドを解除する必要がないことです。 (バインドを解除した場合でも、ハンドラー関数はメモリ内にまだ存在します)。さらに、対応するハンドラーをハンドラー関数に記述していれば、bind(query) を使用して、動的に生成された要素の fastclick イベントを簡単に追加できます。
複数の fastclick イベントを追加し、それらを複数の場所に登録する必要がある場合は、新しい FastClickEvent オブジェクトを作成して、対応する要素にバインドするだけです。
以下はEventTargetクラスの利用方法です。まず、カスタム クラスの追加、削除、実装に使用されるインターフェイスである EventTarget
function EventTarget(){ this.handlers = {}; } EventTarget.prototype = { constructor: EventTarget, addHandler : function(type,handler){ if(typeof this.handlers[type] == "undefined"){ this.handlers[type]=[]; } this.handlers[type].push(handler); }, fire : function(event){ if(!event.target){ event.target = this; } if(this.handlers[event.type] instanceof Array){ var handlers = this.handlers[event.type]; for(var i=0,len=handlers.length;i<len;i++){ handlers[i](event); } } }, removeHandler : function(type,handler){ if(this.handlers[type] instanceof Array){ var handlers = this.handlers[type]; for(var i=0,len=handler.length;i<len;i++){ if(handlers[i]==handler){ break; } } handlers.splice(i,1); } } }
クラスを見てみましょう。 『JavaScript Advanced Programming Third Edition』P616-617 を参照してください
それでは、このクラスを fastclick イベント インターフェイスに変えるにはどうすればよいでしょうか?
グローバル変数を定義し、この変数を使用してすべての fastclick イベントの登録、削除、追加を完了します
var FastClick = function(){ var fastclick = new EventTarget(), touchX = 0 , touchY = 0; function handleEvent(event){ switch(event.type) { case 'touchstart': touchX = event.touches[0].clientX; touchY = event.touches[0].clientY; break; case 'touchend': var x = event.changedTouches[0].clientX; var y = event.changedTouches[0].clientY; if(Math.abs(touchX-x)<5||Math.abs(touchY-y)<5) fastclick.fire({type:'fastclick',target:event.target}); break; } }; fastclick.bind = function(query) { var targetList = document.querySelectorAll(query); for(var i=0,len=targetList.length;i<len;i++) { targetList[i].addEventListener('touchstart',handleEvent); targetList[i].addEventListener('touchend',handleEvent); } } Fastclick.unbind = function(query){ var targetList = document.querySelectorAll(query); for(var i=0,len=targetList.length;i<len;i++) { targetList[i].removeEventListener('touchstart',handleEvent); targetList[i].removeEventListener('touchend',handleEvent); } } return fastclick; }();
このグローバル変数 FastClick を使用して、あらゆる fastclick イベントを追加できます。
呼び方について話しましょう。
イベント関数の追加:
FastClick.addHandler('fastclick',function(event){});
イベント関数の削除: //匿名イベントは削除できません
FastClick.removeHandler('fastclick',handler);
要素のバインディング
FastClick.bind("div");
Unbinding
FastClick.unbind("div");
このメソッドを使用して、ハンドラー イベントのevent.targetを予測する必要もあります。このメソッドでは複数の fastclick イベントを追加できますが、実行中にイベントが 1 つずつ順番に実行されるため、実行したくない機能が実行される可能性があります。
の利点は、複数の fastclick イベントを登録し、再度バインドすることなく実行できることです。
例:
FastClick.bind("div"); FastClick.addHandler(handler1); FastClick.addHandler(handler2);
そして、いずれかの div 要素でクイッククリックイベントが発生すると、handler1 と handler2 が順番に実行されます。
removeHandler を呼び出して handler1 または handler2 を削除すると、対応する関数は実行されなくなります。
さらに、ハンドラー関数では、このオブジェクトは配列 FastClick.handlers['fastclick'] であることに注意してください。通常、イベントが発生したオブジェクトを取得するには、event.target を使用します。
このメソッドを使用すると、基本的に上記のメソッドの問題を克服できます。さらに、event.target を予測して大量の FaskClick クラスを生成したくない場合を除き、このオブジェクトに対して new を繰り返すことはあまり意味がありません。効率的ではありません。
初心者向けヘルプ: 特定の要素のバインディング実行関数を実装するにはどうすればよいですか。つまり、FastClick.bind(query,handler); を呼び出して、クエリ条件を満たす要素にハンドラーを追加する fastclick イベントを実装できます。