Javascript 取消绑定匿名函数
有人能告诉我如何“解除绑定”匿名函数吗? JQUERY可以做到这一点,但是我如何在自己的脚本中实现这一功能呢 这是一个场景: 下面的代码将一个“onclick”事件附加到ID为“someDivId”的Div,现在单击该Div,则显示为“clicked!”Javascript 取消绑定匿名函数,javascript,jquery,javascript-events,Javascript,Jquery,Javascript Events,有人能告诉我如何“解除绑定”匿名函数吗? JQUERY可以做到这一点,但是我如何在自己的脚本中实现这一功能呢 这是一个场景: 下面的代码将一个“onclick”事件附加到ID为“someDivId”的Div,现在单击该Div,则显示为“clicked!” var a = document.getElementById('someDivId'); bindEvent(a,'click',function(){alert('clicked!');}); 这很好,问题是如果函数是匿名的,如何将函数
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 );
}
}
就我个人而言(我知道这不是“最好”的方式,因为它确实需要我思考我在做什么),我喜欢在我正在处理的元素的*事件属性上使用
这样做的好处是能够快速轻松地分离事件
var a = document.getElementById('someDivId');
a.onclick = function() {alert("Clicked!");};
// later...
a.onclick = null;
但是,您必须小心,因为如果您尝试添加第二个事件处理程序,它将覆盖第一个事件处理程序。记住这一点,你会没事的。这是jquery的:
我不确定是否可以解除绑定通过javascript附加的匿名函数。如果可能,您可以简单地从DOM中删除元素并重新创建它。这将删除以前附加的任何事件处理程序 JavaScript不提供附加到节点的事件侦听器列表
您可以删除节点的所有事件侦听器,但使用node.cloneNode
方法,请参见此处:
这会克隆节点(显然),但不会克隆附加到该节点的事件侦听器
也可以将空函数绑定为事件侦听器:
function noop() {}
bindEvent(myElement, "click", noop);
最后,经过几个小时的测试和错误,我找到了一个解决方案,也许它不是最好或最有效的,但。。。它起作用了!(在IE9、Firefox 12、Chrome 18上测试)
首先,我要创建两个跨浏览器和辅助addEvent()和removeEvent()方法。(想法取自Jquery的源代码!)
此外,我们还需要某种“容器”来存储附加到元素的事件,如:
HELPERS.EVTS = {};
最后是两个可调用并向用户公开的方法:
下一步是添加事件(Event)并将此事件与特定元素(el)的方法(handler)关联
最后,为特定元素(el)取消附加每个预附加事件(事件)的方法
顺便说一下,要调用此方法,必须执行以下操作:
捕获DOM节点
var a = document.getElementById('some_id');
使用相应的参数调用方法“bindEvent()”
bindEvent('click',function(){alert('say hi');},a);
并将其拆下:
removeAllEvent('click',a);
仅此而已,希望总有一天会对某些人有用。你从哪里得到的bindEvent()
?它是做什么的?你是在问一个非基于jQuery的答案(例如纯javascript)?@jfriend00:他想自己实现它-例如,他不使用jQuery,而是问jQuery是如何实现的。@jfriend00,我正在尝试在我自己的脚本中实现从Jquery或任何其他执行相同操作的方法解除绑定。a.onclick=null的可能重复项不起作用,这是因为函数bindEvent()以不同的方式运行,请检查原始问题:我将编辑它,并发布bindEvent()的代码多亏了jlaceda的一个想法,我找到了解决问题的解决方案。这只是jQuery事件系统的一小部分。它将如何回答这个问题?@amnotiam我认为这是jquery中事件移除过程中“最简单”的部分,在创建自定义解除绑定函数时将是有用的参考。但你是对的,这不是一个完整的答案。我将在一个基于此代码段的独立函数中进行编辑。@jlaceda,我将免费等待snipet like gold,非常感谢@感谢你的想法,我找到了一个解决方案,thk@乔希古兹曼np。谢谢你一路来解决这个问题。在查看jquery源代码时,我并没有真正得到帮助程序部分。但是jquery可以做到!所以这不是不可能的@JoshGuzman:jQuery只为每个元素绑定一个处理程序,而不是您传递给它的处理程序。处理程序存储在jQuery.cache
中。它绑定了一个通用处理程序,在调用该处理程序时,它会查看事件对象,查看事件的类型,查找元素上的序列号,查看序列号是否存在于jQuery.cache
中,如果存在,检查是否为当前事件类型提供了任何处理程序,如果有,则调用它/它们。jQuery.cache
中也引用了jQuery绑定的通用处理程序,因此在解除绑定时,它会执行类似的查找,并将其传递给解除绑定处理程序的本机方法。当然,当您执行.unbind('click')
时,只需清除jQuery.cache
@amnotiam中的click
处理程序,观察效果非常好!任何实现这一机制的方法???@JoshGuzman:我能推荐的最佳方法是避免。它要求您创建一个系统来管理缓存
数据,并将您与之联系起来。因为从元素到缓存中的数据的唯一连接是元素上的序列号,所以无论何时从DOM中删除元素,都必须查找缓存
条目,如果存在,则清除数据。如果你在管理系统之外冒险从DOM中删除一个元素,你会有内存泄漏。但是我绑定到元素的函数是匿名的,这意味着我没有名称引用,所以我不能覆盖它们或知道它们。啊,是的,我忘了你可以为同一个事件设置多个事件侦听器。无法获取对匿名函数的引用。如果你能改变你的代码,使它不是匿名的,那将是最好的解决方案。否则,您只需关闭所有事件侦听器并添加所需的侦听器,然后重新启动。我不确定HELPERS.EVT[el]
行(其中el
是对DOM元素的引用)是否正在执行您认为它正在执行的操作。JavaScript属性名,我不确定是否有
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;
}
var a = document.getElementById('some_id');
bindEvent('click',function(){alert('say hi');},a);
removeAllEvent('click',a);