有人可以告诉如何“解除绑定”匿名函数吗? JQUERY它能够做到这一点,但我如何在我自己的脚本中实现这个功能。
这是情景:
以下代码将“onclick”事件附加到Div上,其中“someDivId”为ID,现在点击DIV,显示“点击!”。
var a = document.getElementById('someDivId');
bindEvent(a,'click',function(){alert('clicked!');});
这一切都很棒,问题是如果函数是匿名的,如何将函数“取消附加”到DIV,或者如何将所有附加事件“取消附加”到'a'元素?
unBind(a,'click'); //Not necessarily the given params, it's just an example.
这是bindEvent方法的代码:
function bindEvent (el,evtType,fn){
if ( el.attachEvent ) {
el['e'+evtType+fn] = fn;
el[evtType+fn] = function(){
fn.call(el,window.event);
}
el.attachEvent( 'on'+evtType, el[evtType+fn] );
} else {
el.addEventListener( evtType, fn, false );
}
}
答案 0 :(得分:4)
最后,经过几个小时的测试和错误后,我找到了解决方案,也许它不是最好的或最有效的......但它的工作原理! (在IE9,Firefox 12,Chrome 18上测试)
首先,我要创建两个跨浏览器和辅助的addEvent()和removeEvent()方法。 (来自Jquery的源代码的想法!)
HELPERS.removeEvent = document.removeEventListener ?
function( type, handle,el ) {
if ( el.removeEventListener ) {
//W3C Standard
el.removeEventListener( type, handle, true );
}
} :
function( type, handle,el ) {
if ( el.detachEvent ) {
//The IE way
el.detachEvent( 'on'+type, el[type+handle] );
el[type+handle] = null;
}
};
HELPERS.addEvent = document.addEventListener ?
function( type, handle,el ) {
if ( el.addEventListener ) {
//W3C Standard
el.addEventListener( type, handle, true );
}
} :
function( type, handle,el ) {
if ( el.attachEvent ) {
//The IE way
el['e'+type+handle] = handle;
el[type+handle] = function(){
handle.call(el,window.event);
};
el.attachEvent( 'on'+type, el[type+handle] );
}
}
我们还需要某种“容器”来将附加事件存储到元素中,如下所示:
HELPERS.EVTS = {};
最后两个可调用并向用户公开方法: 下一个添加事件(事件)并将此事件与特定元素(el)的方法(处理程序)相关联。
function bindEvent(event, handler,el) {
if(!(el in HELPERS.EVT)) {
// HELPERS.EVT stores references to nodes
HELPERS.EVT[el] = {};
}
if(!(event in HELPERS.EVT[el])) {
// each entry contains another entry for each event type
HELPERS.EVT[el][event] = [];
}
// capture reference
HELPERS.EVT[el][event].push([handler, true]);
//Finally call the aux. Method
HELPERS.addEvent(event,handler,el);
return;
}
最后,取消附加特定元素(el)的每个预先附加事件(事件)的方法
function removeAllEvent(event,el) {
if(el in HELPERS.EVT) {
var handlers = HELPERS.EVT[el];
if(event in handlers) {
var eventHandlers = handlers[event];
for(var i = eventHandlers.length; i--;) {
var handler = eventHandlers[i];
HELPERS.removeEvent(event,handler[0],el);
}
}
}
return;
}
顺便说一句,要调用此方法,您必须执行以下操作: 捕获DOM节点
var a = document.getElementById('some_id');
使用相应的参数调用方法'bindEvent()'。
bindEvent('click',function(){alert('say hi');},a);
并取消它:
removeAllEvent('click',a);
这就是全部,希望有一天对某人有用。
答案 1 :(得分:2)
就个人而言(我知道这不是“最好的”方式,因为它确实需要我思考我正在做的事情),我喜欢只使用元素的on*
事件属性和我一起工作。
这样可以快速轻松地分离事件。
var a = document.getElementById('someDivId');
a.onclick = function() {alert("Clicked!");};
// later...
a.onclick = null;
但是,你必须要小心,因为如果你尝试添加第二个事件处理程序,它将覆盖第一个。记住这一点,你应该没事。
答案 2 :(得分:1)
我不确定你是否可以取消绑定通过javascript附加的匿名功能。如果可能,您可以简单地从DOM中删除元素并重新创建它。这将消除以前附加的任何事件处理程序。
答案 3 :(得分:1)
JavaScript不提供附加到节点的事件侦听器列表。
您可以删除节点的所有事件侦听器,但使用Node.cloneNode
方法,请参阅此处:https://developer.mozilla.org/En/DOM/Node.cloneNode
这会克隆节点(显然),但它不会克隆附加到它的事件侦听器。
您也可以将空函数绑定为事件侦听器:
function noop() {}
bindEvent(myElement, "click", noop);
答案 4 :(得分:-1)
这是来自jquery的source:
jQuery.removeEvent = document.removeEventListener ?
function( elem, type, handle ) {
if ( elem.removeEventListener ) {
elem.removeEventListener( type, handle, false );
}
} :
function( elem, type, handle ) {
if ( elem.detachEvent ) {
elem.detachEvent( "on" + type, handle );
}
};