背景
JavaScriptでAddEventListener()またはAttachEvent()を使用してイベントをバインドする場合、いくつかの小さな問題があります。
1。AddEventListener()またはAttachEvent()を使用して追加された匿名関数を削除できません。
コードコピーは次のとおりです。varobtn = document.getElementById( 'btn');
obtn.addeventlistener( 'click'、function(){
アラート( 'ボタンがクリックされます')
}、間違い)
obtn.reomveeventlistener( 'click'、function(){
アラート( 'ボタンがクリックされます')
}、間違い)
//匿名関数が渡されるため、OBTNのイベントは削除できません
2。IE6-IE8では、複数のイベントの逆注文実行問題は、actiblevent()を使用して境界を掲載しています。
コードコピーは次のとおりです。
var obtn = document.getElementById( 'btn');
obtn.attachevent( 'onclick'、function(){
アラート(1)
})
obtn.attachevent( 'onclick'、function(){
アラート(2)
})
obtn.attachevent( 'onclick'、function(){
アラート(3)
})
// EIE9+実行注文1、2、3
// IE6-IE8 3、2、1の下での実行注文
問題を解決します
後で再利用できるように、クロスブラウザーイベントバインディングモジュールを書きたいと同時に、アピールの問題を解決したいと思います。 jQueryは、イベントキューとデータキャッシュメカニズムを使用して、この問題を解決します。関連するソースコードを見ました。それは本当に複雑でした。私は自分でいくつかの方法を試して、ほとんど実装しませんでした。コードはオブジェクト指向で投稿されており、人々がそれを複雑に見させたくないので、それを関数に変更して整理します。
コードコピーは次のとおりです。
/*バインディングイベントインターフェイス
*
*@param {dom-dom}および{type-string}および{fn-function}オプションパラメーター{fnname-string}
*@イベントキューを作成し、DOMオブジェクトプロパティに追加します。
イベントハンドラー(関数)をイベントキューに追加します
識別子をイベントハンドラーに追加して、指定されたイベントハンドラーを削除できます
*/
関数bind(dom、type、fn、fnname){
dom.eventqueue = dom.eventqueue || {};
dom.eventqueue [type] = dom.eventqueue [type] || {};
dom.handler = dom.handler || {};
if(!fnname){
var index = queuelength(dom、type);
dom.eventqueue [type] ['fnqueue'+index] = fn;
}
それ以外 {
dom.eventqueue [type] [fnname] = fn;
};
if(!dom.handler [type])bindevent(dom、type);
};
/*バインディングイベント
*
*@param {dom-dom}および{type-string}
*@実行イベントは一度だけバインドされ、ハンドラーは実行イベントキューでイベントハンドラー(関数)を通過するために使用されます
*@caller bind()
*/
function bindevent(dom、type){
dom.handler [type] = function(){
for(dom.eventqueue [type]のvar guid){
dom.eventqueue [type] [guid] .call(dom);
}
};
if(window.addeventlistener){
dom.addeventlistener(type、dom.handler [type]、false);
}
それ以外 {
dom.attachevent( 'on'+type、dom.handler [type]);
};
};
/*イベントのインターフェイスを削除します
*
*@param {dom-dom}および{type-string}オプションパラメーター{fnname-function}
*@識別子がない場合は実行、unbindevent()を実行します
識別子がある場合、指定されたイベントハンドラーが削除されます。イベントキューの長さが0の場合、unbindevent()が実行されます。
*/
function unbind(dom、type、fnname){
var hasqueue = dom.eventqueue && dom.eventqueue [type];
if(!hasqueue)return;
if(!fnname){
unbindevent(dom、type)
}
それ以外 {
dom.eventqueue [type] [fnname];
if(queuelength(dom、type)== 0)unbindevent(dom、type);
};
};
/*イベントを削除します
*
*@param {dom-dom}および{type-string}
*@executeバウンドイベントハンドラーを削除し、イベントキューをクリアします
*@caller unbind()
*/
関数unbindevent(dom、type){
if(window.removeeventlistener){
dom.removeeventlistener(type、dom.handler [type])
}
それ以外 {
dom.detachevent(type、dom.handler [type])
}
dom.eventqueue [type];
};
/*イベントキューの長さを判断します
*
*@param {dom-dom}および{type-string}
*@caller bind()unbind()
*/
function queuelength(dom、type){
var index = 0;
for(dom.eventqueue [type]のvarの長さ){
インデックス++;
}
戻りインデックス。
};
使い方
コードコピーは次のとおりです。
var obtn = document.getElementById( 'btn');
//バインディングイベント
//ボタンの3つのクリックイベント機能を同時にバインドします
// IE6-IE8に基づく実行命令は変更されていません
bind(obtn、 'click'、function(){
アラート(1);
})
bind(obtn、 'click'、function(){
アラート(2);
}、 'myfn')
bind(obtn、 'click'、function(){
アラート(3);
})
//イベントを削除します
//すべてのバインドされたクリックイベント機能を削除し、匿名関数の削除をサポートします
unbind(obtn、 'click')
//識別子myfnを使用してイベント関数のみを削除します
unbind(obtn、 'click'、 'myfn')
プログラムのアイデア
このプログラムの主なアイデアは、グローバル環境を汚染することなく、DOM要素オブジェクトの属性としてDOM要素オブジェクトの属性としてイベントキューを追加することです。これにより、異なるイベントタイプに結合するさまざまなDOM要素の複数のイベント関数のデータストレージの問題を解決できます。
コードコピーは次のとおりです。
// dom要素のイベントキュー
dom {
eventqueue:{
'クリック' : {
fnqueue1:関数、
myfn:関数、
fnqueue3:関数
}
「マウスオーバー」:{
fnqueue1:関数、
fnqueue2:関数
}
}
}
毎回、イベント関数は最初に対応するイベントタイプのイベントキューに追加され、イベントは1回のみバインドされます。イベントがトリガーされると、ハンドラーイベント関数が実行され、ハンドラーは実行イベントキューでイベント関数を横断します。
unbind()は、着信識別子がない場合はすべてのバインドされたイベント関数を削除し、匿名関数の削除をサポートし、識別子がある場合は指定されたイベント関数を削除します。
プログラムロジックは複雑ではなく、バグやパフォーマンスの問題がある場合があります。興味がある場合は、ガイドしてコミュニケーションをとることができます。