Функция Javascript выполняется только через раз

#javascript #removechild

#javascript #removechild

Вопрос:

Я работаю над игрой в угадывание букв, и внизу у меня есть табло, которое показывает, сколько жизней осталось у игрока, прежде чем он проиграет игру. У меня есть экранная клавиатура, на которую пользователь нажимает, чтобы выбрать, какую букву они хотят угадать.

Все работает нормально, за исключением удаления «жизней» игрока. У меня есть жизни в виде изображений, которые находятся в упорядоченном списке. При каждом нажатии кнопки функция проверяет, совпадает ли это нажатие кнопки с буквой во фразе. Если этого не произойдет, необходимо удалить ресурс из упорядоченного списка и добавить 1 к количеству пропущенных.

Добавление 1 к пропущенным значениям срабатывает при каждом неправильном нажатии кнопки, но удаление сердечка срабатывает только при любом другом, и я не уверен, почему. Любая помощь была бы высоко оценена.

 function checkLetter(clickedButton) {
  const letters = document.getElementsByClassName('letter');
  let letterFound = null;
  for (let i = 0; i < letters.length; i  = 1) {
    if (clickedButton === letters[i].textContent) {
      letters[i].classList.add('show');
      letterFound = true;
    }
  }
  return letterFound;
}

function changeScore() {
  let scoreboardList = document.querySelector('ol');
  scoreboardList.removeChild(scoreboardList.childNodes[0]);
}

qwerty.addEventListener('click', (e) => {
  const button = e.target;
  const buttonText = button.textContent;
  checkLetter(buttonText);
  if (checkLetter(buttonText) == null) {
    missed  = 1;
    changeScore();
    console.log(missed);
  } else {
    button.classList.add('chosen');
  }
});  
    

 <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Wheel of Success!</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="css/styles.css" rel="stylesheet">
  </head>
  <body>
    <div class="main-container">
      <div id="overlay" class="start">
        <h2 class="title">Wheel of Success</h2>
        <a class="btn__reset">Start Game</a>
      </div>

      <div id="banner" class="section">
        <h2 class="header">Wheel of Success</h2>
      </div>

      <div id="phrase" class="section">
        <ul></ul>
      </div>
      <div id="qwerty" class="section">
        <div class="keyrow">
          <button>q</button><button>w</button><button>e</button><button>r</button><button>t</button><button>y</button><button>u</button><button>i</button><button>o</button><button>p</button>
        </div>
        <div class="keyrow">
          <button>a</button><button>s</button><button>d</button><button>f</button><button>g</button><button>h</button><button>j</button><button>k</button><button>l</button>
        </div>
        <div class="keyrow">
          <button>z</button><button>x</button><button>c</button><button>v</button><button>b</button><button>n</button><button>m</button>
        </div>
      </div>

      <div id="scoreboard" class="section">
        <ol>
          <li class="tries"><img src="images/liveHeart.png" height="35px" width="30px"></li>
          <li class="tries"><img src="images/liveHeart.png" height="35px" width="30px"></li>
          <li class="tries"><img src="images/liveHeart.png" height="35px" width="30px"></li>
          <li class="tries"><img src="images/liveHeart.png" height="35px" width="30px"></li>
          <li class="tries"><img src="images/liveHeart.png" height="35px" width="30px"></li>
        </ol>
      </div>
    </div>
    <script type="text/javascript" src="js/app.js"></script>
  </body>
</html>  

Комментарии:

1. Я сделал для вас фрагмент. Пожалуйста, добавьте соответствующие html и css, чтобы исправить ошибку консоли. Что такое qwerty, например

2. Вам не нужно дважды запускать функцию контрольного списка в прослушивателе событий. Наличие ее в таком операторе if приведет к ее запуску. Либо это, либо присвоите ее переменной в первый раз и вместо этого вычислите это.

Ответ №1:

Из того, что я могу сказать, ваш вызов scoreboardList.removeChild(scoreboardList.childNodes[0]); удалит первый узел. В вашем случае это не обязательно элемент, но также может быть текстовым узлом, содержащим только пробелы. Вероятно, это причина, по которой только каждый второй вызов выглядит так, как будто он что-то делает. Другая — удаление пробелов. Я изменил код, чтобы вместо этого явно удалить первый узел «heart». И, конечно, то, что Льюис упомянул в своем комментарии: не вызывайте checkLetter дважды. Просто используйте ее в if напрямую.

 let missed = 0;

function changeScore() {
  let scoreboardList = document.querySelector('ol');

  // !!!!!! These two lines are the important changes:
  let heart = scoreboardList.querySelector('li:first-child'); // find first heart item
  scoreboardList.removeChild(heart); // remove the heart
}

document.addEventListener('click', (e) => {
  //const button = e.target;
  //const buttonText = button.textContent;
  //if (checkLetter(buttonText) == null) {
    missed  = 1;
    changeScore();
    console.log(missed);
  //} else {
  //  button.classList.add('chosen');
  //}
});  
 <div id="scoreboard" class="section">
  <ol>
    <li class="tries"><img src="http://pngimg.com/uploads/heart/heart_PNG51341.png" height="35px" width="30px"></li>
    <li class="tries"><img src="http://pngimg.com/uploads/heart/heart_PNG51341.png" height="35px" width="30px"></li>
    <li class="tries"><img src="http://pngimg.com/uploads/heart/heart_PNG51341.png" height="35px" width="30px"></li>
    <li class="tries"><img src="http://pngimg.com/uploads/heart/heart_PNG51341.png" height="35px" width="30px"></li>
    <li class="tries"><img src="http://pngimg.com/uploads/heart/heart_PNG51341.png" height="35px" width="30px"></li>
  </ol>
</div>  

Ответ №2:

Просто обновите свой changeScore() метод следующим образом:

 function changeScore() {
  let scoreboardList = document.querySelector('ol');

  // Replace this
  // scoreboardList.removeChild(scoreboardList.childNodes[0]);

  // By this 'EDIT'
  scoreboardList.removeChild(scoreboardList.querySelector('li:first-child'));
}
  

Это приведет к удалению сердечка каждый раз, когда ответ будет ложным.

Комментарии:

1. Ваш код должен быть var heart = scoreboardList.querySelector('li:first-child'); scoreboardList.removeChild(heart); . Она не будет работать так, как написано сейчас, поскольку heart никогда не определяется.

2. Это сработало! Спасибо за вашу помощь. Высоко ценится.