gpt4 book ai didi

Javascript 事件 addEventListener 为同一功能注册多次;使用 OOP Javascript

转载 作者:搜寻专家 更新时间:2023-11-01 05:11:27 25 4
gpt4 key购买 nike

我正在使用面向对象的 Javascript,并结合注册事件监听器。根据我对事件监听器的理解,如果应用于 eventtarget 的函数已经被注册,则重复尝试添加相同的事件监听器将被忽略。换句话说,它应该只触发一次。但在下面的代码中并非如此(也可以在 jsfiddle 上看到)。

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener

Multiple identical event listeners

If multiple identical EventListeners are registered on the same EventTarget with the same parameters, the duplicate instances are discarded. They do not cause the EventListener to be called twice, and since the duplicates are discarded, they do not need to be removed manually with the removeEventListener method.

http://jsfiddle.net/qd1e8f6c/

HTML

<div id="wrapper">
<input id="t1" type="text" />
<input id="btn" type="button" />
</div>

JS

var namespace = namespace || {};

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);
}
};

namespace.ExampleClass = function() {
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 namespace.ExampleClass();

inst.init( textbox, button );

namespace.event.addListener(textbox, "focus");
namespace.event.addListener(button, "click");

// same handle -- shoudln't it only add the event once?
namespace.event.addListener(textbox, "focus");
namespace.event.addListener(button, "click");

正如您在上面代码的最后几行中看到的,一个名为 addListener 的函数被执行了两次,它为每个输入注册了一个事件。然后,再次执行addListener。我希望它不会再次注册并忽略,但它实际上注册了。我不明白。名为 handle 的命名空间中的函数完全相同。我在这里做错了什么?

任何帮助都会很棒。

最佳答案

您不能将相同的类型/函数对绑定(bind)到一个元素。但是,这不是您正在做的,您是在每次调用 namespace.addEventListener 函数时显式创建一个新的 handler 函数。

你有什么:

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 命名空间是通过 Module Pattern 完成的

例如,对于您的情况,您似乎并不真正关心通过这个“命名空间”变量让您的代码在全局范围内可访问,因为它仅在您的代码中使用,因此您可以这样做:

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
}
};
})();

关于Javascript 事件 addEventListener 为同一功能注册多次;使用 OOP Javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26127336/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com