更改类元素不会停止.click事件的工作

时间:2017-01-14 01:08:44

标签: javascript jquery

我有10个元素,类名为“英雄”。我用jQuery“.click”事件使它们可以点击。单击它们后,我使用“.attr”函数更改了它们的类名。而且,当我检查它们时,他们将他们的班级名称改为“fixheroes”。

然而,这并不能阻止“.click”事件继续在它们上运行。我不希望这样。

您可以在此处找到代码:

http://codepen.io/anon/pen/KaMBmM

jQuery / JS

var counter = 1;
var picked = ["0", "0", "0", "0", "0", "0", "0"]

$(".heroes").click(function(e) {


    var id = this.id;
    var heroInt = id.substring(1, 3);

    picked[counter] = heroInt;




    var left = ["0", "21.5%", "32.9%", "44.3%", "55.7%", "67.1%", "21.5%", "32.9%", "44.3%", "55.7%", "67.1%"];


    $("#" + id).attr('class', "fixheroes fix" + heroInt);


    var h0 = document.getElementsByClassName('h0');
    var fixnow = document.getElementsByClassName("fix" + heroInt);
    fixnow[0].style.left = left[heroInt];

    if (heroInt > 5) {
        fixnow[0].style.top = (h0[0].offsetHeight + h0[0].getBoundingClientRect().top)



    } else {
        fixnow[0].style.top = "10%"

    }


    var ani = ".fix" + heroInt;



    if (counter == 1) {
        $(ani).animate({

            top: "5%",
            left: "3%",

        }, 1000, function() {});
    }

    if (counter == 2) {
        $(ani).animate({

            left: "85.6%",
            top: "5%",

        }, 1000, function() {});
    }
    if (counter == 3) {
        $(ani).animate({

            left: "3%",
            top: "35%",

        }, 1000, function() {});
    }
    if (counter == 4) {
        $(ani).animate({

            left: "85.6%",
            top: "35%",

        }, 1000, function() {});
    }
    if (counter == 5) {
        $(ani).animate({

            left: "3%",
            top: "65%",

        }, 1000, function() {});
    }
    if (counter == 6) {
        $(ani).animate({

            left: "85.6%",
            top: "65%",

        }, 1000, function() {});
    }



    counter += 1;


});

CSS:

.h {
    align-self: center;
    width: 96%;
    height 100%;
    border-style: solid;
    border-width: 0px;
    border-color: 817B6F;
}
.heroes {
    display: flex;
    justify-content: center;
    background-color: 817B6F;
    position: absolute;
    width: 10%;
    height: auto;
    padding: 0.7%;
    border-width: 1px;
    border-color: black;
    border-style: solid;
}

.fixheroes {
    display: flex;
    justify-content: center;
    background-color: 817B6F;
    position: absolute;
    width: 10%;
    height: auto;
    padding: 0.7%;
    border-width: 1px;
    border-color: black;
    border-style: solid;
}

.h0 {left: -20%; top:10%}
.h1 {left: 21.5%; top:10%;  border-top-left-radius: 5px;}
.h2 {left: 32.9%; top:10%;}
.h3 {left: 44.3%; top:10%;}
.h4 {left: 55.7%; top:10%;}    
.h5 {left: 67.1%; top:10%; border-top-right-radius: 5px; top:10%;}
.h6 {left: 21.5%; top:50%; border-bottom-left-radius: 5px;}
.h7 {left: 32.9%; top:50%;}
.h8 {left: 44.3%; top:50%;}
.h9 {left: 55.7%; top:50%;}    
.h10{left: 67.1%; top:50%; border-bottom-right-radius: 5px;}

HTML:

<div class="heroes h1" id="h1" >
<img class= "h" name= "Warrior" src="https://placehold.it/256" />
</div>


<div class="heroes h2" id="h2">
 <img class= "h" name= "Warrior" src="https://placehold.it/256" />
</div>



<div class="heroes h3" id="h3">
<img class= "h" name= "Warrior" src="https://placehold.it/256" />
</div>


<div class="heroes h4" id="h4">
<img class= "h" name= "Warrior" src="https://placehold.it/256" />
</div>

<div class="heroes h5" id="h5">
<img class= "h" name= "Warrior" src="https://placehold.it/256" />
</div>

<div class="heroes h6" id="h6">
<img class= "h" name= "Warrior" src="https://placehold.it/256"/>
</div>

<div class="heroes h7" id="h7">
<img class= "h" name= "Warrior" src="https://placehold.it/256" />
</div>


<div class="heroes h8" id="h8">
<img class= "h" name= "Warrior" src="https://placehold.it/256" />
</div>

<div class="heroes h9" id="h9">
<img class= "h" name= "Warrior" src="https://placehold.it/256" />
</div>

<div class="heroes h10" id="h10">
<img class= "h" name= "Warrior" src="https://placehold.it/256" />
</div>

我做了一个测试函数,这个方法可以工作:

http://codepen.io/anon/pen/LxZrKO

那么我的代码有什么问题?

4 个答案:

答案 0 :(得分:3)

这是因为绑定事件时,它会根据选择器条件绑定到DOM节点。绑定后,除非删除,否则事件侦听器将始终处于活动状态。在这种情况下,click事件处理程序绑定到DOM就绪的所有.heroes元素,即使在更改其类之后,这些DOM节点也会绑定click事件。

要考虑动态类更改(以便类中的更改将“删除”事件处理程序),只需将click事件处理程序绑定到更高级别的父级(或document对象)。我诚实地认为,这是我解决问题的方式,而不是必须通过凌乱的unbind()off()方法。

$(document).on('click', '.heroes', function(e) { ... }

.on()事件将自动过滤来自任何具有类heroes的子节点的点击事件。因此,如果动态更新类,这个技巧仍然有效。 同样,这就是为什么.on() +过滤选择器是将事件绑定到动态添加元素的推荐方法的原因。在这种情况下,我们正在寻找动态添加的元素,而不是动态类更改。

以下是您更新过的单行更改小提琴:http://codepen.io/anon/pen/BpzPVN

此外,关于最小示例,相同的修复也同样有效:

$(document).on('click', '.test', function(e) { 
   console.log('Class changed to test2');
   $(".test").attr('class', "test2");
});
.test {
  position: absolute;
  height: 200px;
  width: 200px;
  background-color: red;
}

.test2 {
  position: absolute;
  height: 200px;
  width: 200px;
  background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">
  click me
</div>

答案 1 :(得分:0)

`.click()'处理程序与元素本身绑定,而不是类选择器。你可以通过几种不同的方式让它停止工作。

  1. 在更改类之前,还要删除处理程序: $(".heroes").off("click");

  2. 将处理程序放在父级而不是子级上: $("#parentdiv").on("click", ".heroes", function() {});

答案 2 :(得分:0)

点击处理程序会在代码运行时立即添加一次。现在,无论你对元素做了什么,它都会永远听取对该元素的点击。

当您说$(".heroes").click时,您不是说“仅触发具有.heroes类的内容的点击事件”。您正在说“立即向所有.heroes添加点击事件。

我修复它的方法是将$(this).unbind("click");添加到函数的开头以删除点击处理程序。

答案 3 :(得分:0)

问题是事件处理程序仍然附加到元素。 要修复,只需在更改课程之前添加$("#" + id).off("click");