任何人都可以告诉我为什么' tileClick'事件监听器没有被删除在这个功能的底部?代码完整无缺,我没有错误。我甚至可以在for循环中抛出console.log并打印出所有DOM元素。但是,事件监听器仍然存在。我被困了!
function tileSelection(dieTotal) {
var openTiles = document.getElementsByClassName('openTile'),
dieAmountLeft = dieTotal;
document.getElementById('total').innerHTML = dieAmountLeft;
for(var i=0; i<openTiles.length; i++){
openTiles[i].addEventListener('click',function tileClick(){
// TODO: Must remove event listener!!!
this.classList.toggle('selectedTile');
if(this.classList.contains('selectedTile')){
dieAmountLeft -= parseInt(this.getAttribute('data-tile-val'));
if(dieAmountLeft >= 0){
document.getElementById('total').innerHTML = dieAmountLeft;
}else{
dieAmountLeft += parseInt(this.getAttribute('data-tile-val'));
this.classList.toggle('selectedTile');
}
} else {
dieAmountLeft += parseInt(this.getAttribute('data-tile-val'));
document.getElementById('total').innerHTML = dieAmountLeft;
}
if(dieAmountLeft === 0){
for(var t=0; t<openTiles.length; t++){
openTiles[t].removeEventListener('click',tileClick);
}
newTurn();
}
});
}
}
答案 0 :(得分:0)
将您的函数分配给变量
喜欢
var myfunc = function () {}
然后
做
openTiles[t].removeEventListener('click',myfunc);
答案 1 :(得分:0)
您可以使用以下方式分配功能:
openTiles[i].addEventListener('click',function tileClick(){ ... }, ...)
命名函数表达式的名称仅在函数本身中可用,它不可用于封闭的执行上下文(buggy versions of IE除外)。
如果你想删除一个监听器,你需要引用它,所以你应该这样做:
function titleClick(){...}
...
openTiles[i].addEventListener('click', tileClick, ...)
这样当您删除侦听器时,您可以将其引用为 titleClick 。
由于您在函数内调用remove,因此它只引用与该元素关联的函数实例,即 titleClick 的每个实例仅对其自身具有引用。
您正在为每个元素附加 openTile 的新实例,因此每个元素只有一个对自身的引用,因此它只会删除它自己的侦听器。在其他元素上调用它没有任何效果,因为如果 removeEventListener 找不到匹配的函数,它什么都不做。该方法没有返回值,因此您无法从调用结果中判断它是否“有效”。
E.g。在下面,单击 foo 0 只会从自身中删除侦听器,您必须单击另一个按钮才能删除其侦听器。
<button class="foo">foo 0</button>
<button class="foo">foo 1</button>
<script>
var foos = [].slice.call(document.getElementsByClassName('foo'));
foos.forEach(function(el) {
el.addEventListener('click',function bar(){
console.log('clicked on ' + this.textContent);
foos.forEach(function(el) {el.removeEventListener('click', bar)});
}, false);
});
</script>
将脚本更改为:
var foos = [].slice.call(document.getElementsByClassName('foo'));
function bar(){
console.log('clicked on ' + this.textContent);
foos.forEach(function(el) {el.removeEventListener('click', bar)});
}
foos.forEach(function(el) {
el.addEventListener('click', bar, false);
});
修复了这一点,因为现在只有一个 bar 实例,每个侦听器都引用一个实例。您可以根据需要添加任意数量的按钮,本例中我只使用了两个按钮。
请注意,不建议将[].slice.call
与主机对象一起使用,在使用中的某些浏览器中会失败。我使用它是为了方便,for循环对于将HTMLCollection转换为数组更加可靠。