繁体   English   中英

为什么onclick事件监听器被删除了?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM