背景
addEventListener() またはattachEvent() を使用して JavaScript でイベントをバインドする場合、いくつかの小さな問題があります。
1. addEventListener() またはattachEvent() を使用して追加された匿名関数は削除できません。
var oBtn = document.getElementById('btn');
oBtn.addEventListener('click',function(){
alert('ボタンがクリックされました')
},false)
oBtn.reomveEventListener('click', function() {
alert('button is clicked')
},false)
//匿名関数が
に渡されるため、oBtn のイベントを削除できません 2. ie6 - IE8 では、attachEvent() を使用して複数のイベントをバインドすると、逆順序で実行される問題があります。
var oBtn = document.getElementById('btn ');
oBtn.attachEvent('onclick',function(){
alert(1)
})
oBtn.attachEvent('onclick',function() {
アラート(2)
})
oBtn.attachEvent('onclick',function(){
アラート(3)
})
//ie9 次へ実行順序 1 , 2, 3
//ie6-ie8 での実行順序 3, 2, 1
問題を解決してください
将来再利用できるように、クロスブラウザーのイベント バインディング モジュールを作成したいと考えています。同時に、アピールの問題も解決したいと考えています。 JQuery は内部でイベント キューとデータ キャッシュ メカニズムを使用してこの問題を解決しています。関連するソース コードを調べたところ、それが非常に複雑であることがわかり、自分でいくつかの方法を試し、なんとか解決できました。私が投稿したコード スニペットは、もともとオブジェクト指向で書かれていたので、複雑にしたくなかったので、関数に変更しました。
/*イベントをバインディングするためのインターフェース
*
*@param {dom-DOM}、{type-string}、および {fn-function} のオプションのパラメーター {fnName-string}
* @execute イベント キューを作成し、DOM オブジェクト属性に追加します
イベント ハンドラー (関数) をイベント キューに追加します
イベント ハンドラーに識別子を追加して、指定したイベント ハンドラーを削除できます
*/
function binding(dom,type,fn,fnName){
dom.eventQueue = dom.eventQueue ||
dom.eventQueue[type] = dom.eventQueue[type] | {};
dom.handler = dom.handler || {};
if (!fnName) {
varindex = queueLength(dom,type);
dom.eventQueue [ type]['fnQueue' インデックス] = fn;
}
else {
dom.eventQueue[type][fnName] = fn;
};
if (! dom .handler[type]) bindingEvent(dom,type);
};
/*バインドイベント
*
*@param {dom-DOM} および {type-string }
*@execute イベントを 1 回だけバインドします。ハンドラーは実行イベント キュー内のイベント ハンドラー (関数) を走査するために使用されます
*@caller binding()
*/
function bindingEvent(dom, type ){
dom.handler[type] = function(){
for(var guid in dom.eventQueue[type]){
dom.eventQueue[type][guid].call(dom) ;
}
};
if (window.addEventListener) {
dom.addEventListener(type,dom.handler[type],false);
}
else {
dom.attachEvent('on' type,dom.handler[type]);
};
};
/*イベントを削除するためのインターフェース
*
* @param {dom-DOM} および {type-string} のオプションパラメータ {fnName-function}
*@execute 識別子がない場合は unBindEvent() を実行
識別子がある場合は指定されたイベント ハンドラを削除、イベントキューの長さが 0 の場合、unBindEvent()
*/
function unBind(dom,type,fnName){
var hasQueue = dom.eventQueue && dom.eventQueue[type]; を実行します。 > if (!hasQueue) return;
if (!fnName) {
unBindEvent(dom,type)
}
else {
delete dom.eventQueue[type][fnName] ;
if (queueLength(dom,type) == 0) unBindEvent(dom,type);
} > *@param {dom-DOM} および {type-string}
*@execute バインドを削除しますイベント ハンドラー handler を実行し、イベント キューをクリアします
*@caller unBind()
*/
function unBindEvent(dom,type){
if (window.removeEventListener) {
dom.removeEventListener( type,dom.handler[type])
}
else {
dom.detachEvent(type,dom.handler[type])
}
delete dom.eventQueue[type] ];
};
/*イベントキューの長さを判断します
*
*@param {dom-DOM} および {type-string}
*@caller binding() unBind ()
*/
function queueLength(dom,type){
var インデックス = 0;
for (dom.eventQueue[type] の var length){
インデックス ;
}
インデックスを返します;
};
使用方法
コードをコピー
コードは次のとおりです:
var oBtn = document.getElementById('btn');
//イベントのバインド
//ボタンの 3 つのクリック イベント関数を同時にバインドします
//ie6 - 実行順序は、ie8
bind(oBtn,'click',function(){
alert(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 : function,
myfn : function,
fnQueue3 : function
}
'mouseover' : {
fnQueue1 : 関数,
fnQueue2 : 関数
}
}
}
イベント関数は毎回、対応するイベント タイプのイベント キューに追加され、イベントは 1 回だけバインドされます。イベントがトリガーされると、ハンドラー イベント関数が実行され、ハンドラーはイベント キュー内のイベント関数をたどって実行します。
unBind() は、識別子が渡されない場合はバインドされたすべてのイベント関数を削除し、匿名関数の削除をサポートし、識別子がある場合は指定されたイベント関数を削除します。
プログラムのロジックは複雑ではありません。バグやパフォーマンスの問題がある可能性があります。興味があれば、ガイダンスとコミュニケーションを提供できます。