我使用此结构创建一次性点击事件:
function structure() {
this.elements = document.getElementsByClassName('className');
this.numElements = this.elements.length;
for(var i = 0; i < this.numElements; i++) {
this.elements[i].addEventListener('click', this.elementClicked.bind(this));
}
}
这些事件的处理程序实现如下:
structure.prototype.elementClicked = function(e) {
// ... processing event
for(var i = 0; i < this.numElements; i++) {
this.elements[i].removeEventListener('click', arguments.callee);
}
};
如果点击了任何已注册的元素,那么想法是触发处理程序一次,然后从每个元素中取消注册事件
不幸的是,每次点击其中一个已注册的项目时,处理程序仍会被解雇
我知道匿名函数不能用于引用同一个对象,但是指定arguments.callee或引用函数的整个名称仍然没有帮助原因
答案 0 :(得分:1)
每次打电话......
<div class="wrapper">
<div class="flex-container">
<div class="box one"></div>
<div class="box two"></div>
</div>
</div>
... this.elements[i].addEventListener('click', this.elementClicked.bind(this));
创建方法的另一个实例。它使用bind
,true,但在其他方面是完全不同的功能。这就是为什么你不会使用this.elementClicked
上调用的remoteEventListener删除它。
解决方法是什么?一个可能的选项 - 将this.elementClicked
作为{ once: true }
param传递 - 已在评论中给出,但IE和Edge不支持它(很可能不会被您在最近的Safari中支持未来)。这是另一种方法:
addEventListener
现在为function Structure() {
this.elements = document.getElementsByClassName('className');
this.numElements = this.elements.length;
// reassign a bound method onto instance:
this.elementClicked = this.elementClicked.bind(this);
for(var i = 0; i < this.numElements; i++) {
this.elements[i].addEventListener('click', this.elementClicked);
}
}
Structure.prototype.elementClicked = function(e) {
// ... processing event
for(var i = 0; i < this.numElements; i++) {
this.elements[i].removeEventListener('click', this.elementClicked);
}
};
对象的每个实例创建一个绑定的elementClicked
方法,并将其上下文永久设置。
答案 1 :(得分:1)
另一种方法是让您的对象实现 EventListener 接口。您可以通过向构造函数的handleEvent
添加.prototype
方法,然后传递对象本身来代替事件处理程序来完成此操作。
function Structure() {
this.elements = document.getElementsByClassName('className');
this.numElements = this.elements.length;
for(var i = 0; i < this.numElements; i++) { // v-- pass the object
this.elements[i].addEventListener('click', this);
}
}
// Implement the interface; gets invoked when an event occurs
Structure.prototype.handleEvent = function(e) {
// Used a switch statement in anticipation of other event types
switch (e.type) {
case "click":
this.elementClicked(e);
break;
}
};
Structure.prototype.elementClicked = function(e) {
// ... processing event
for(var i = 0; i < this.numElements; i++) { // v-- pass the object
this.elements[i].removeEventListener('click', this);
}
};
现在不再需要使用.bind()
了。相反,this
中handleEvent
的值将是绑定对象。您仍然可以通过e.currentTarget
获取处理程序绑定到的元素。