我有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
那么我的代码有什么问题?
答案 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()'处理程序与元素本身绑定,而不是类选择器。你可以通过几种不同的方式让它停止工作。
在更改类之前,还要删除处理程序:
$(".heroes").off("click");
将处理程序放在父级而不是子级上:
$("#parentdiv").on("click", ".heroes", function() {});
答案 2 :(得分:0)
点击处理程序会在代码运行时立即添加一次。现在,无论你对元素做了什么,它都会永远听取对该元素的点击。
当您说$(".heroes").click
时,您不是说“仅触发具有.heroes
类的内容的点击事件”。您正在说“立即向所有.heroes
类添加点击事件。”
我修复它的方法是将$(this).unbind("click");
添加到函数的开头以删除点击处理程序。
答案 3 :(得分:0)
问题是事件处理程序仍然附加到元素。
要修复,只需在更改课程之前添加$("#" + id).off("click");
。