![](/img/trans.png)
[英]Why doesn't the event listener gets removed immediately after the function gets executed?
[英]Why does the onclick event listener gets removed?
我正在用JavaScript制作一个小型配对游戏。 为什么首次成功尝试后onclick侦听器会停止工作。 如何解决此问题。
我希望将侦听器附加到id为“ leftSide”的div的最后一个子元素上,即使我先通过删除旧节点来刷新所有节点也是如此。
<!DOCTYPE html>
<html>
<head>
<title>Matching Game</title>
<style>
img {
position: absolute;
}
div {
position: absolute;
width: 500px;
height: 500px;
}
#rightSide {
left: 500px;
border-left: 1px solid black;
}
</style>
</head>
<body>
<h2>Matching Game</h2>
<p>Click on the extra smile on the left</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
<script>
var numberOfFaces = 5;
var theLeftSide = document.getElementById("leftSide");
var theRightSide = document.getElementById("rightSide");
function generateFaces() {
for (var i=0; i<=numberOfFaces; i++) {
new_img = document.createElement("img");
new_img.src="smile.png";
new_img.style.top=String(Math.floor(Math.random()*400))+"px";
new_img.style.left=String(Math.floor(Math.random()*400))+"px";
theLeftSide.appendChild(new_img);
}
// Clone all images to right side
leftSideImages = theLeftSide.cloneNode(true);
leftSideImages.removeChild(leftSideImages.lastChild);
theRightSide.appendChild(leftSideImages);
}
generateFaces()
var theBody = document.getElementsByTagName("body")[0];
theBody.onclick = function gameOver() {
alert("Game Over!");
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
};
theLeftSide.lastChild.onclick = function nextLevel(event) {
// remove child nodes
while (theLeftSide.firstChild) {
theLeftSide.removeChild(theLeftSide.firstChild);
}
while (theRightSide.firstChild) {
theRightSide.removeChild(theRightSide.firstChild);
}
// new nodes
event.stopPropagation();
numberOfFaces += 5;
generateFaces();
};
</script>
</body>
</html>
您可以尝试这样的事情:
<!DOCTYPE html> <html> <head> <title>Matching Game</title> <style> img { position: absolute; } div { position: absolute; width: 500px; height: 500px; } #rightSide { left: 500px; border-left: 1px solid black; } </style> </head> <body> <h2>Matching Game</h2> <p>Click on the extra smile on the left</p> <div id="leftSide"></div> <div id="rightSide"></div> <script> var numberOfFaces = 5; var theLeftSide = document.getElementById("leftSide"); var theRightSide = document.getElementById("rightSide"); var clickLastChild = function clickLastChild() { // remove child nodes theLeftSide.lastChild.onclick = function (event) { while (theLeftSide.firstChild) { theLeftSide.removeChild(theLeftSide.firstChild); } while (theRightSide.firstChild) { theRightSide.removeChild(theRightSide.firstChild); } // new nodes event.stopPropagation(); numberOfFaces += 5; generateFaces(); }; }; function generateFaces() { for (var i = 0; i <= numberOfFaces; i++) { new_img = document.createElement("img"); new_img.src = "smile.png"; new_img.style.top = String(Math.floor(Math.random() * 400)) + "px"; new_img.style.left = String(Math.floor(Math.random() * 400)) + "px"; theLeftSide.appendChild(new_img); } // Clone all images to right side leftSideImages = theLeftSide.cloneNode(true); leftSideImages.removeChild(leftSideImages.lastChild); theRightSide.appendChild(leftSideImages); clickLastChild(); } generateFaces(); var theBody = document.getElementsByTagName("body")[0]; theBody.onclick = function gameOver() { alert("Game Over!"); theBody.onclick = null; theLeftSide.lastChild.onclick = null; }; clickLastChild(); </script> </body> </html>
问题是当您将事件处理程序附加到元素时,当该元素被销毁时,事件也消失了(GC清理时)。 theLeftSide.lastChild
不会创建对theLeftSide
最后一个子元素的theLeftSide
。 它创建对当前最后一个孩子的引用。
您必须更改将事件处理程序添加到generateFaces
函数内部的位置,因此,每次更改theLeftSide
子级时,您将再次获得最后一个子级,并添加事件。
看下面的例子:
<!DOCTYPE html> <html> <head> <title>Matching Game</title> <style> img { position: absolute; } div { position: absolute; width: 500px; height: 500px; } #rightSide { left: 500px; border-left: 1px solid black; } </style> </head> <body> <h2>Matching Game</h2> <p>Click on the extra smile on the left</p> <div id="leftSide"></div> <div id="rightSide"></div> <script> var numberOfFaces = 5; var theLeftSide = document.getElementById("leftSide"); var theRightSide = document.getElementById("rightSide"); function generateFaces() { for (var i = 0; i <= numberOfFaces; i++) { new_img = document.createElement("img"); new_img.src = "http://www.webgranth.com/wp-content/uploads/2012/03/smile.png"; new_img.style.top = String(Math.floor(Math.random() * 400)) + "px"; new_img.style.left = String(Math.floor(Math.random() * 400)) + "px"; theLeftSide.appendChild(new_img); } // Clone all images to right side leftSideImages = theLeftSide.cloneNode(true); leftSideImages.removeChild(leftSideImages.lastChild); theRightSide.appendChild(leftSideImages); theLeftSide.lastChild.onclick = nextLevel; } generateFaces() var theBody = document.getElementsByTagName("body")[0]; theBody.onclick = function gameOver() { alert("Game Over!"); theBody.onclick = null; theLeftSide.lastChild.onclick = null; }; function nextLevel(event) { // remove child nodes while (theLeftSide.firstChild) { theLeftSide.removeChild(theLeftSide.firstChild); } while (theRightSide.firstChild) { theRightSide.removeChild(theRightSide.firstChild); } // new nodes event.stopPropagation(); numberOfFaces += 5; generateFaces(); }; </script> </body> </html>
注意:我已经简单地将theLeftSide.lastChild.onclick = function nextLevel(event) {
更改为一个简单的函数声明: function nextLevel(event) {
,然后将事件处理程序添加到generateFaces
函数内部: theLeftSide.lastChild.onclick = nextLevel;
。
在这里,我做了充分发挥作用的jsfiddle
您还必须通过场景调用游戏中的generateFaces()
。 是的,就像@epascarello提到的那样,将点击事件设置为null会丢失点击事件。
因为您将onclick设置为false
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
当您单击tbody时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.