javascript解除绑定事件未解除绑定,即使它已触发

javascript解除绑定事件未解除绑定,即使它已触发,javascript,unbind,Javascript,Unbind,我有一些代码,当在对象内部调用时,会将页面上的元素绑定到单击。当我再次按下开始按钮时,元素被更新,并且我正在为再次单击添加事件侦听器。在再次添加偶数侦听器之前,我正在解除事件侦听器的绑定,它将触发10次以解除绑定。。。然后我绑定,它会触发10次以读取绑定。。。但是当我检查元素或单击元素时,它会激发两次。如果我再按一下“开始”,它现在会发射三次 card.clickFn = function() { if(Game.cardsClickedHistory.length<

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

    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); 
card.clickFn=函数(){

如果(Game.cardslickedhistory.length当您通过调用构造函数
新卡实例化卡对象时(cf.cardDivs[i]);
,构造函数创建的新函数不是上次构造中的上一个函数。因此,当它试图删除侦听器时,显然找不到上一个侦听器。为了避免这种情况,您可以设置一个存储绑定侦听器的静态变量(
侦听器
)。然后在下一次调用
build()
function可以轻松找到准确录制的前一绑定函数作为侦听器。我在您的代码中添加了一些功能,使其能够正常工作

<!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>

.card{宽度:200px;高度:200px;背景:红色;边距:10px;}
重新绑定
var卡=功能(元素){
var卡=此;
card.element=元素;
card.clickFn=函数(){
控制台日志(“点击卡”);
}
var listener=Card.listeners.filter(函数(lis){return lis.ele==element})[0];
if(侦听器!==未定义){
card.element.removeEventListener(“单击”,listener.func);
Card.listeners=Card.listeners.filter(函数(lis){return lis.ele!==element});//删除以前的侦听器记录
}
card.element.addEventListener(“单击”,card.clickFn);
Card.listeners.push({ele:element,func:Card.clickFn});//添加监听器的记录
}
Card.listeners=[];//静态成员
var CardFactory=函数()
{
var cf=此;
cf.cardDivs=document.getElementsByClassName(“卡”);
cf.build=function(){

对于(var i=0;i当您通过调用构造函数
新卡实例化卡对象时(cf.cardDivs[i]);
,构造函数创建的新函数不是上次构造中的上一个函数。因此,当它试图删除侦听器时,显然找不到上一个侦听器。为了避免这种情况,您可以设置一个存储绑定侦听器的静态变量(
侦听器
)。然后在下一次调用
build()
function可以轻松找到准确录制的前一绑定函数作为侦听器。我在您的代码中添加了一些功能,使其能够正常工作

<!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>

.card{宽度:200px;高度:200px;背景:红色;边距:10px;}
重新绑定
var卡=功能(元素){
var卡=此;
card.element=元素;
card.clickFn=函数(){
控制台日志(“点击卡”);
}
var listener=Card.listeners.filter(函数(lis){return lis.ele==element})[0];
if(侦听器!==未定义){
card.element.removeEventListener(“单击”,listener.func);
Card.listeners=Card.listeners.filter(函数(lis){return lis.ele!==element});//删除以前的侦听器记录
}
card.element.addEventListener(“单击”,card.clickFn);
Card.listeners.push({ele:element,func:Card.clickFn});//添加监听器的记录
}
Card.listeners=[];//静态成员
var CardFactory=函数()
{
var cf=此;
cf.cardDivs=document.getElementsByClassName(“卡”);
cf.build=function(){

对于(变量i=0;请提供一个。您是否可以在调用之间重新分配
卡。单击fn
?它需要是相同的函数,而不仅仅是相同的变量。这是否在重新分配
卡的循环中?请提供一个。您是否可以在调用之间重新分配
卡。单击fn
?它需要是相同的函数,而不仅仅是相同的变量可以。这是否在重新分配
卡的循环中?