Javascript事件addEventListener为同一函数多次注册;使用OOP-Javascript
我正在使用面向对象的Javascript,同时注册事件侦听器。根据我对事件监听器的理解,如果应用于eventtarget的函数已经注册,那么重复添加同一事件监听器的尝试将被忽略。换句话说,它应该只发射一次。但在下面的代码中并非如此(也可以在JSFIDLE上看到) 多个相同的事件侦听器 如果在具有相同参数的同一EventTarget上注册了多个相同的EventListener,则会丢弃重复的实例。它们不会导致EventListener被调用两次,并且由于重复项被丢弃,因此不需要使用removeEventListener方法手动删除它们 HTML 正如您在上面代码的最后几行中所看到的,一个名为Javascript事件addEventListener为同一函数多次注册;使用OOP-Javascript,javascript,oop,events,dom-events,addeventlistener,Javascript,Oop,Events,Dom Events,Addeventlistener,我正在使用面向对象的Javascript,同时注册事件侦听器。根据我对事件监听器的理解,如果应用于eventtarget的函数已经注册,那么重复添加同一事件监听器的尝试将被忽略。换句话说,它应该只发射一次。但在下面的代码中并非如此(也可以在JSFIDLE上看到) 多个相同的事件侦听器 如果在具有相同参数的同一EventTarget上注册了多个相同的EventListener,则会丢弃重复的实例。它们不会导致EventListener被调用两次,并且由于重复项被丢弃,因此不需要使用removeE
addListener
的函数被执行两次,它向每个输入注册一个事件。然后,再次执行addListener
。我希望它不会再次注册并忽略,但它确实注册了。我不明白。命名空间中名为handle
的函数完全相同。我做错了什么
任何帮助都很好。不能将同一类型/函数对绑定到元素。但是,这不是您要做的,您在每次调用
名称空间.addEventListener
函数时都显式地创建一个新的处理程序
函数
你所拥有的:
namespace.event = {
addListener: function(el, type) {
var handle = function() {
switch (type) {
case "focus":
console.log(el.value);
break;
case "click":
console.log(el.id + " was clicked");
break;
}
};
el.addEventListener(type, handle, false);
}
};
你希望做什么
var handle = function(evt) {
var el = evt.currentTarget;
switch (type) {
case "focus":
console.log(el.value);
break;
case "click":
console.log(el.id + " was clicked");
break;
}
};
namespace.event = {
addListener: function(el, type) {
el.addEventListener(type, handle, false);
}
};
因为在第二种情况下,handle
只有一个实例
名称空间
您所拥有的是一种名称空间方法,但现在,JS名称空间通常是通过
例如,对于您的情况,您甚至似乎并不真正关心如何通过这个“namespace”变量全局访问您的代码,因为它只在您的代码中使用,所以您可以:
var namespace = (function(){
function handle(evt) {
var el = evt.currentTarget;
switch (type) {
case "focus":
console.log(el.value);
break;
case "click":
console.log(el.id + " was clicked");
break;
}
};
function addListener(el, type) {
el.addEventListener(type, handle, false);
}
function ExampleClass() {
this.init = function(el1, el2) {
el1.value = "123";
el2.value = "Click Me";
};
};
var textbox = document.getElementById("t1");
var button = document.getElementById("btn");
var inst = new ExampleClass();
inst.init( textbox, button );
addListener(textbox, "focus");
addListener(button, "click");
// And if you do care about 'inst' being global, you'd explicitly add it to the window.
window.inst = inst;
// Whatever functions you want to expose as 'namespace' would go here.
return {
event: {
addEventListener: addEventListener
}
};
})();
你没有做任何事情来阻止它添加两次事件,不知道为什么你会期望它自动这样做。因为我的印象是,如果目标相同,句柄相同,addEventListener不会再次注册事件。我只是在addEventListener上粘贴了mozilla链接的引用。除非我读错了,而且可能是,否则我将其解释为事件只会触发一次。对不起,当然是@loganfsmyth对此进行了解释。非常感谢您提供的示例!我非常感激。问题?如果我将
句柄
函数作为名称空间
的一个子集,addEventListener会只触发一次吗?如果可能的话,我想将函数声明保存在名称空间中。再次感谢。那很好,因为还有一个函数实例。我能问一下为什么这些都需要存在于名称空间中吗?这是一个丑陋的方法,可能有更好的方法。当然,你可以。我正在修改供应商程序的一些功能以进行修复(供应商没有提供修复,所以我是修复它的信使)。这些供应商函数可以在同一会话中重复调用。因此,我需要确保事件只注册一次。我不想影响他们无数的JS文件;因此,我将所有内容都放在自己的名称空间中。如果有更好的方法,我很乐意听到。这是我能想到的最好的方法,不会与供应商的代码冲突。哦,哇。非常感谢你的教育。我一定会仔细阅读链接并尝试实现这一点。再次感谢你!你好我不知道如何将此转移到讨论中,但有一个更正。我确实希望我的代码可以在全球范围内访问。我在自己的JS文件中创建名称空间和类。然后我在供应商的程序中引用JS文件。我还修改了供应商的一些JS函数,以及我创建的名称空间和类。我不知道我是否还能像链接讨论的那样使用闭包,但我肯定会尝试一下。非常感谢。
var handle = function(evt) {
var el = evt.currentTarget;
switch (type) {
case "focus":
console.log(el.value);
break;
case "click":
console.log(el.id + " was clicked");
break;
}
};
namespace.event = {
addListener: function(el, type) {
el.addEventListener(type, handle, false);
}
};
var namespace = (function(){
function handle(evt) {
var el = evt.currentTarget;
switch (type) {
case "focus":
console.log(el.value);
break;
case "click":
console.log(el.id + " was clicked");
break;
}
};
function addListener(el, type) {
el.addEventListener(type, handle, false);
}
function ExampleClass() {
this.init = function(el1, el2) {
el1.value = "123";
el2.value = "Click Me";
};
};
var textbox = document.getElementById("t1");
var button = document.getElementById("btn");
var inst = new ExampleClass();
inst.init( textbox, button );
addListener(textbox, "focus");
addListener(button, "click");
// And if you do care about 'inst' being global, you'd explicitly add it to the window.
window.inst = inst;
// Whatever functions you want to expose as 'namespace' would go here.
return {
event: {
addEventListener: addEventListener
}
};
})();