- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用面向对象的 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.
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/
我想在按下按钮时打开一个表单,然后在完成表单后创建另一个按钮以将数据存储在对象中。 我这样做了,但在第二个 addEventListener 中它给了我这个错误: cannot read proper
这是我实际代码的简化版本。 有三个复选框和按钮(每个编号为 0、1、2)和一个提交按钮。简而言之,如果您选中复选框编号 1 和 2,单击提交,按钮 1 和 2 将被着色。现在您可以单击任何彩色按钮,它
问题代码 var el = document.getElementById("searchcharm_'"+touch_id+"'"); el.addEventListener('click',
window.document.addEventListener = function(event) {...} window.addEventListener = function(event) {
这段代码块有什么区别: var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", uploadProgress,
在使用 PhoneGap 时,它有一些使用 document.addEventListener 的默认 JavaScript 代码,但我有自己的代码使用 window.addEventListener
当我运行这段代码时,为什么 .body 事件先触发? document.addEventListener('click', function() { console.log('The docume
我将带有循环的 addEventListener 添加到一些 anchor 元素 products 中,如下所示: for(var j=0;j
所以我的代码可以按我想要的方式工作,但是大多数(IE 除外)调试器都会向我抛出此错误: 未捕获类型错误:无法读取未定义的属性“addEventListener” 这是代码: //Get all ele
我真的不知道为什么这不起作用。在我的 HTML 中,如果我将脚本放在 head 部分,我会在控制台中收到以下错误: Uncaught TypeError: Cannot read property '
在 React 中,当你有一个带有 onClick 属性的元素时,很容易使用 Enzyme 的 .simulate("click") 方法来点击它。然而,在我的代码库中有一个示例,其中一个元素被 Re
问候,由于某种原因,当我单击按钮时,我的 -addEventListener 没有执行。任何人都可以帮忙这是我的代码: function elNegro() { alert("Thank Yo
我正在将我的一些代码从 onClick 更改为 addEventListener,因为我已经阅读了各种好处,并且出于关注点分离的目的。然而,我遇到的问题之一是,虽然使用 onClick,我能够调用一个
我正在尝试向我在循环中生成的某些元素添加事件监听器。我必须使用 div.lastChild - 虽然在这个例子中它非常愚蠢。但这只是演示: var func = function() {
我在将事件监听器添加到 JS 时遇到问题...如果我将按钮与 onclick 属性连接,它会起作用,但如果我在 HTML 中删除它并尝试添加 eventListener('click', myFunc
我不知道为什么,但是当我点击“按钮”时什么也没有发生... 控制台中没有消息,没有错误。如何解决? JS var bird = (function(){ let button = doc
我正在绘制一个方框网格,希望能够单击每个方框并使用 SocketIO 将带有其 ID 的通知发送到服务器 let boxes = document.querySelecto
我想是新手问题。 以下代码是我在文档就绪时调用的函数的一部分。它旨在在鼠标移动时永久返回当前鼠标位置的值。 正在发生的奇怪事情:在文档就绪时移动鼠标不会将任何内容记录到控制台。我知道 mouse_mo
我是 Flash 的新手,我似乎无法完成这个简单的操作。 (我正在使用 ActionScript 3.0) 我在我的编辑器中创建了一个输入文本框。实例名称是“测试”。在我的 Action 编辑器中,我
我有一个像 那些标签包含一些内容,我想打开/关闭它们,但仅使用纯 javascript。我已经尝试过使用 document.querySelectorAll
我是一名优秀的程序员,十分优秀!