javascript - Javascript事件addEventListener为相同的函数注册多次;使用 OOP

  显示原文与译文双语对照的内容
67 1

我在使用面向对象的Javascript,同时注册事件监听器。 从我对事件侦听器的了解,如果应用到,的函数已经注册,那么将忽略这个事件侦听器。 换句话说,它应该只激发一次。 但是代码 below ( 在jsfiddle上也可以看到) 中并没有这样的情况。

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

多个相同的事件侦听器

如果在相同的EventTarget上使用相同的参数注册多个相同的EventListeners,则会丢弃重复的实例。 它们不会引发两次调用,因为重复被丢弃,因这里不需要手动删除with方法。

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 再次执行。 我希望它不会再次被 register 和忽略,但它实际上是寄存器。 我不明白名称空间中名为 handle的函数完全相同。 我 在 这儿 写错 了 吗?

任何帮助都很有用。 非常感谢。

时间: 原作者:

126 5

不能将同一类型/函数对绑定到元素。 但是,这不是你所做的,你在每次调用 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命名空间是通过模块 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


 }


 };


})();



原作者:
...