【问题标题】:javascript unbind event not unbinding even though it firedjavascript unbind 事件即使被触发也不会解除绑定
【发布时间】:2020-12-10 08:25:51
【问题描述】:

我有一些代码,当在对象内部调用时,将页面上的元素绑定到点击。当我再次按下开始按钮时,元素会更新,并且我正在添加一个事件侦听器以再次单击。我在再次添加偶数侦听器之前取消绑定事件侦听器,它会触发 10 次以解除绑定...然后我绑定,它会触发 10 次以读取绑定...但是。当我检查元素或单击元素时,它会触发两次。如果我再次点击开始,它现在会触发 3 次......

    card.clickFn = function() {
        if(Game.cardsClickedHistory.length<2 && Game.status==1){
            card.element.style.backgroundImage = card.image;
            Game.cardClicked(card); // notify a card clicked
        } 
    }
    card.element.removeEventListener("click", card.clickFn);
    card.element.addEventListener("click", card.clickFn); 

可重复的例子

<!DOCTYPE html>
<html>
<head>
    <title></title>

    <style>
        .card {width: 200px; height: 200px; background: red; margin: 10px;}
    </style>
</head>
<body>

    <div id="cards">
        <div class="card"></div>
        <div class="card"></div>
    </div>

    <button id="rebind">REBIND</button>

<script>

var Card = function(element){
    var card = this;
    card.element = element;

    card.clickFn = function(){
        console.log("Clicked card");
    }
    card.element.removeEventListener("click", card.clickFn);
    card.element.addEventListener("click", card.clickFn);
}

var CardFactory = function()
{
    var cf = this;
    cf.cardDivs = document.getElementsByClassName("card");

    cf.build = function(){
        for(var i=0;i<cf.cardDivs.length; i++)
        {
            new Card(cf.cardDivs[i]);
        }
    }
}

var oCF = new CardFactory();
oCF.build();

document.getElementById("rebind").addEventListener("click", oCF.build)



</script>
</body>
</html>

【问题讨论】:

  • 您可以在通话之间重新分配card.clickFn 吗?它需要是同一个函数,而不仅仅是同一个变量。
  • 这是在你重新分配card的循环中吗?

标签: javascript unbind


【解决方案1】:

当您通过调用构造函数 new Card(cf.cardDivs[i]); 来实例化 Card 对象时,构造函数会创建新函数,该函数不是上次构造中的先前函数。因此当它试图移除监听器时,显然找不到之前的监听器。为避免这种情况,您可以设置一个 static 变量 (listeners) 来存储绑定的侦听器。然后在 build() 函数的下一个 cal 上很容易找到准确记录的先前绑定函数作为侦听器。我在您的代码中添加了一些可以正常工作的功能。

<!DOCTYPE html>
<html>
<head>
    <title></title>

    <style>
        .card {width: 200px; height: 200px; background: red; margin: 10px;}
    </style>
</head>
<body>

    <div id="cards">
        <div class="card"></div>
        <div class="card"></div>
    </div>

    <button id="rebind">REBIND</button>

<script>

var Card = function(element){
    var card = this;
    card.element = element;

    card.clickFn = function(){
        console.log("Clicked card");
    }
    
    var listener=Card.listeners.filter(function(lis){ return lis.ele===element })[0];
   if(listener!==undefined){
        card.element.removeEventListener("click",  listener.func);
        Card.listeners=Card.listeners.filter(function(lis){return lis.ele!==element}); // remove previous listener record
   }
    card.element.addEventListener("click", card.clickFn);
    Card.listeners.push({ele:element,func:card.clickFn}); // add record of listener

}
Card.listeners=[]; //static member
var CardFactory = function()
{
    var cf = this;
    cf.cardDivs = document.getElementsByClassName("card");

    cf.build = function(){
        for(var i=0;i<cf.cardDivs.length; i++)
        {
            new Card(cf.cardDivs[i]);
        }
    }
}

var oCF = new CardFactory();
oCF.build();

document.getElementById("rebind").addEventListener("click", oCF.build)



</script>
</body>
</html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多