2015-10-01 5 views
1

Я делаю небольшую совпадающую игру в javascript. Почему прослушиватель onclick перестает работать после первой успешной попытки. Как исправить эту проблему.Почему прослушиватель событий onclick удаляется?

Я ожидаю, что слушатель будет прикреплен к последнему дочернему элементу div с id «leftSide» даже после обновления всех узлов, сначала удалив старые узлы.

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

'generateFaces()' без точки с запятой, сразу после объявления функции. Сохраняется ли в вашем коде? – hrust

+0

Просто попробовал, та же проблема. –

ответ

1

Проблема заключается в том, когда вы прикрепляете обработчик события к элементу, когда этот элемент уничтожается, событие также исчезает (когда GC очищает). theLeftSide.lastChild не создает ссылку на любой последний дочерний элемент из 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>


Примечания: Я simpled изменил theLeftSide.lastChild.onclick = function nextLevel(event) {, к простому объявлению функции: function nextLevel(event) {, а затем добавили обработчик события внутри generateFaces функция: theLeftSide.lastChild.onclick = nextLevel;.

-1

Потому что вы установили OnClick к ложному

theBody.onclick = null; 
theLeftSide.lastChild.onclick = null; 

при нажатии TBODY.

1

вы могли бы попробовать что-то вроде этого:

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

0

Здесь я сделал полностью рабочий jsfiddle

Вы должны вызвать generateFaces() от игры над сценарием также. И да, как упоминалось в @epascarello, вы теряете события кликов, когда вы устанавливаете их в null.

+1

У вашего кода были те же проблемы, что и упомянутый выше Sourabh ... Ваш lastchild.click должен быть в файле generateFaces() – sijones