受け入れられた回答が示すように、ハンドラーをDOMに直接バインドするとハンドラーの量が制限されるという事実は別として、addEventListener
提供できることは他にもたくさんあります
。イベントリスナーは要素に直接バインドする必要はありません(する必要はありません) DOM に存在します)。.on
これは ajax を使用する場合に便利です (jQuery のメソッドと考えてください)。
1 つのリスナーで特定のタイプのすべてのイベントを処理できるため、イベント リスナーを使用すると必要なリソースが少なくて済みます (これにより、全体的なパフォーマンスが向上します)
。
window.onload = function(e)
{
alert('In IE8, this causes mem-leaks!');
};
var load = function(e)
{//cf @PaulS.'s comment & link on IE8 and symbol bleeding
e = e || window.event;//X-browser stuff
var target = e.target || e.srcElement;//so you can use this callback for all browsers
if (window.removeEventListener)
{//more X-browser stuff
return window.removeEventListener('load',load,false);
}
window.detachEvent('onload',load);//reference callback by variable name
};
if (window.addEventListener)
{
window.addEventListener('load',load,false);
}
else
{//in IE8, addEventListener doesn't exist, but it has a jScript counterpart:
//no mem-leaks in IE AFAIK
window.attachEvent('onload', load);
}
興味のあるリンクがいくつかあります (はい、知っています。恥知らずな自己宣伝です。申し訳ありません)。
なぜイベントリスナーが必要なのですか?
IE8 でのメモリ リークとイベント委任とクロージャ
そしてちょっとした楽しみとして、私がしばらく前に書いた、イベント委任を使用し、IE、FF、chrome、およびタッチ デバイスで動作するスクリプトを紹介します。これは私が予想していたよりも少しトリッキーでした。
/**
* Copyright 2012, Elias Van Ootegem
* Date: Tue Jul 03 2012 +0100
*/
(function(G,undef)
{
'use strict';
var load,clickHandler,touchHandler,hide,reveal;
hide = function(elem)
{
elem.setAttribute('style','display:none;');
};
reveal = function(show,nextTo)
{
var str = 'display: block; position:relative; left:220px; top: ' + (nextTo.offsetTop - show.parentNode.offsetTop) + 'px;';
show.setAttribute('style',str);
}
load = function()
{
var doc = G.document;
if (G.removeEventListener)
{
G.removeEventListener('load',load,false);
}
else
{
G.detachEvent('onload',load);
}
if (doc.hasOwnProperty('ontouchstart'))
{//We have a touch device
touchHandler = (function(subNavs)
{
var current,divs = (function()
{
var i,r = {};
for (i=0;i<subNavs.length;i++)
{
r[subNavs[i].id] = doc.getElementById(subNavs[i].id + 'd');
hide(r[subNavs[i].id]);
}
return r;
}());
return function(e)
{
e = e || G.event;
if (e.changedTouches.length !== 1)
{//multi-touch
return e;
}
var timer,endListener,coords,target = e.target || e.srcElement;
if (target.tagName.toLowerCase() === 'img' && target.id.match(/^close[0-9]+$/))
{
hide(current);
current = undef;
return e;
}
if (target.tagName.toLowerCase() === 'a')
{
target = target.parentNode;
}
if (target.tagName.toLowerCase() !== 'p' || !target.id || !divs[target.id])
{
if (current === undef)
{
return e;
}
while(target !== doc.body)
{
target = target.parentNode;
if (target === current)
{
return e;
}
}
timer = setTimeout(function()
{
doc.body.removeEventListener('touchend',endListener,false);
clearTimeout(timer);
timer = undef;
},300);
endListener = function(e)
{
doc.body.removeEventListener('touchend',endListener,false);
clearTimeout(timer);
timer = undef;
hide(current);
current = undef;
return e;
};
return doc.body.addEventListener('touchend',endListener,false);
}
coords = {x:e.changedTouches[0].clientX,y:e.changedTouches[0].clientY};
timer = setTimeout(function()
{
doc.body.removeEventListener('touchend',endListener,false);
clearTimeout(timer);
timer = undef;
},300);
endListener = function(e)
{
e = e || G.event;
clearTimeout(timer);
timer = undef;
doc.body.removeEventListener('touchend',endListener,false);
var endCoords,endTarget = e.target || e.srcElement;
if (endTarget !== target)
{
endCoords = {x:e.changedTouches[0].clientX,y:e.changedTouches[0].clientY};
if (Math.abs(coords.x - endCoords.x) < 26 && Math.abs(coords.y - endCoords.y) < 26)
{
endTarget = target;
}
}
if (endTarget !== target)
{
return e;
}
if (current !== undef)
{
hide(current);
current = undef;
}
current = divs[target.id];
reveal(current,target);
};
doc.body.addEventListener('touchend',endListener,false);
};
}(doc.getElementsByClassName('subnavbar')));
return doc.body.addEventListener('touchstart',touchHandler,false);
}
clickHandler = (function(subNavs)
{
var current,divs = (function()
{
var i,r = {};
for (i=0;i<subNavs.length;i++)
{
r[subNavs[i].id] = doc.getElementById(subNavs[i].id + 'd');
hide(r[subNavs[i].id]);
}
return r;
}());
return function(e)
{
e = e || G.event;
var target = e.target || e.srcElement;
if (target.tagName.toLowerCase() === 'img' && target.id.match(/^close[0-9]+$/))
{
hide(current);
current = undef;
return e;
}
if (target.tagName.toLowerCase() === 'a')
{
target = target.parentNode;
}
if (target.tagName.toLowerCase() !== 'p' || !target.className.match(/\bsubnavbar\b/))
{
if (current !== undef)
{
target = (function()
{
while (target !== doc.body)
{
target = target.parentNode;
if (target === current)
{
return current;
}
}
}());
if (target !== current)
{
hide(current);
current = undef;
}
}
return e;
}
if (e.preventDefault)
{
e.preventDefault();
e.stopPropagation();
}
else
{
e.returnValue = false;
e.cancelBubble = true;
}
if (current !== undef)
{
hide(current);
}
current = divs[target.id];
reveal(current,target);
};
}(doc.getElementsByClassName('subnavbar')));
if (doc.body.addEventListener)
{
return doc.body.addEventListener('click',clickHandler,false);
}
return doc.body.attachEvent('onclick',clickHandler);
};
if (G.addEventListener)
{
return G.addEventListener('load',load,false);
}
return G.attachEvent('onload',load);
}(this));