Невозможно заменить текущие элементы изображения новыми изображениями - PullRequest
0 голосов
/ 01 мая 2020

У меня есть сценарий JS, который программирует поведение игры "Set" в веб-браузере. По сути, набор найден, если выбрано 3 карты, так что для каждого атрибута (стиль, цвет, форма, количество) все карты имеют общий атрибут или ни один из карт не имеет этот атрибут.

Когда набор карточек найден, я пытаюсь отобразить сообщение («SET!»), Которое будет отображаться как изображение карточки в течение 1 се c, а затем заменить существующее изображение на новый, уникальный набор атрибутов.

enter image description here enter image description here Я приложил три изображения, чтобы дать более четкое объяснение поведения, которое я пытаюсь получить, когда набор найден. Изображения будут «перезаписаны» для отображения сообщения «SET!» в течение 1 секунды, а затем программа сгенерирует новые случайные атрибуты, которые будут отображаться для замены оригинальных элементов изображения на этой карте.

В настоящее время я получаю ошибку, когда выбираю три карты, которые являются установить "SET!" сообщение появляется для всех трех выбранных карточек, но новые изображения не создаются для замены исходных изображений, а первый выбранный элемент остается пустым после исчезновения сообщения.

enter image description here enter image description here

Визуальный вывод где после SET! сообщение скрыто, те же изображения для 2-й и 3-й выбранной карты все еще находятся там, в то время как изображение 1-й карты вообще не отображается.

Я смотрел на свою функцию hideMessage(selectedCards) (строка 204) и Я вызываю свои функции generateImages и generateRandomAttributes для замены изображений на своих карточках, но я все еще не уверен, почему я получаю такое поведение при запуске моей игры.

Рассматривая различные способы, как Я могу обновить DOM. Будет ли работать такой метод, как replaceChild ()?

"use strict";
(function () {

  // MODULE GLOBAL VARIABLES, CONSTANTS, AND HELPER FUNCTIONS CAN BE PLACED HERE
  let timerId;
  let remainingSeconds;

  let totalCards;
  let easyDifficulty;

  let foundSets = 0;

  const STYLE = ["solid", "outline", "striped"];
  const SHAPE = ["diamond", "oval", "squiggle"];
  const COLOR = ["green", "purple", "red"];
  const COUNT = [1, 2, 3];

  /**
   * Add a function that will be called when the window is loaded.
   */
  window.addEventListener("load", init);

  /**
   * CHANGE: Describe what your init function does here
   */
  function init() {
    id("start-btn").addEventListener("click", toggleView);
    id("back-btn").addEventListener("click", toggleView);
    id("refresh-btn").addEventListener("click", generateSetDeck);
  }

  function toggleView() {
    if (id("game-view").classList.contains("hidden")) {
      id("menu-view").classList.add("hidden");
      id("game-view").classList.remove("hidden");
      startGame();
    } else if (id("menu-view").classList.contains("hidden")) {
      id("menu-view").classList.remove("hidden");
      id("game-view").classList.add("hidden");
      id("refresh-btn").disabled = false;
      foundSets = 0;
      qs("#set-count").textContent = foundSets;
    }
  }

  function startGame() {
    generateSetDeck();
    startTimer();
  }

  function generateSetDeck() {
    id("board").innerHTML = "";
    if (qs("input[type = \"radio\"]:checked").value === "easy") {
      easyDifficulty = true;
      totalCards = 9;
    } else {
      easyDifficulty = false;
      totalCards = 12;
    }
    for (let i = 0; i < totalCards; i++) {
      id("board").appendChild(generateUniqueCard(easyDifficulty));
    }
  }

  function generateRandomAttributes(isEasy) {
    let randStyle;
    if (isEasy === true) {
      randStyle = STYLE[0];
    } else {
      randStyle = STYLE[Math.floor(Math.random() * STYLE.length)];
    }
    var randShape = SHAPE[Math.floor(Math.random() * SHAPE.length)];
    var randColor = COLOR[Math.floor(Math.random() * COLOR.length)];
    var randCount = COUNT[Math.floor(Math.random() * COUNT.length)];
    var randAttributes = [randStyle, randShape, randColor, randCount];
    return randAttributes;
  }

  function generateUniqueCard(isEasy) {
    let randAttributesArray = generateRandomAttributes(isEasy);
    let divCards = generateACard(randAttributesArray);
    let boardChildren = qsa("#board div");
    let board = [];

    for (let i = 0; i < boardChildren.length; i++) {
      board.push(boardChildren[i].id);
    }

    while (board.includes(divCards.id) && board.length > 0) {
      divCards = generateACard(generateRandomAttributes(isEasy));
    }

    divCards.addEventListener("click", cardSelected);
    return divCards;
  }

  function generateACard(randAttributesArray) {
    let card = gen("div");
    card.classList.add("card");
    generateImages(randAttributesArray, card);
    return card;
  }

  function generateImages(randAttributesArray, card) {
    let id = randAttributesArray[0] + "-" + randAttributesArray[1] + "-" + randAttributesArray[2];
    let countID = id + "-" + randAttributesArray[3];
    card.id = countID;
    for (let i = 0; i < randAttributesArray[3]; i++) {
      let imgCards = gen('img');
      imgCards.src = "img/" + id + ".png";
      imgCards.alt = countID;
      card.appendChild(imgCards);
    }
  }


  function startTimer() {
    let timer = qs("select");
    remainingSeconds = timer.options[timer.selectedIndex].value;
    let timerDisplay = formatTimer(remainingSeconds);
    id("time").innerHTML = timerDisplay;
    id("refresh-btn").disabled = false;
    timerId = setInterval(advanceTimer, 1000);
  }

  function formatTimer(timeValue) {
    let minutes = Math.floor(timeValue / 60);
    let seconds = remainingSeconds % 60;

    if (minutes < 10) {
      minutes = "0" + minutes;
    }

    if (seconds < 10) {
      seconds = "0" + seconds;
    }
    return minutes + ":" + seconds;
  }

  function advanceTimer() {
    remainingSeconds--;
    if (remainingSeconds <= 0) {
      remainingSeconds = 0;
      let selectedCards = qsa(".card");
      for (let i = 0; i < selectedCards.length; i++) {
        if (selectedCards[i].classList.contains("selected")) {
          selectedCards[i].classList.remove("selected");
        }
        selectedCards[i].removeEventListener("click", cardSelected);
      }

      id("refresh-btn").disabled = true;
      clearInterval(timerId);
    }
    id("time").textContent = formatTimer(remainingSeconds);
  }

  function cardSelected() {
    if (!this.classList.contains("selected")) {
      this.classList.add("selected");
      let selectedCards = Array.from(qsa(".selected"));

      if (selectedCards.length === 3) {
        for (let i = 0; i < selectedCards.length; i++) {
          selectedCards[i].classList.remove("selected");
        }

        if (isASet(selectedCards)) {
          messageDisplay(selectedCards, "SET!");
          foundSets++;
          qs("#set-count").textContent = foundSets.toString();
        } else {
          messageDisplay(selectedCards, "Not a Set");
        }
        let timeDelay = 1000;
        setTimeout(() => {
          hideMessage(selectedCards);
        }, timeDelay);
      }
    } else {
      this.classList.remove("selected");
    }
  }

  function messageDisplay(selectedCards, displayMessage) {
    for (let i = 0; i < selectedCards.length; i++) {
      let msg = gen("p");
      msg.textContent = displayMessage;
      selectedCards[i].classList.add("hide-imgs");
      selectedCards[i].appendChild(msg);
    }
  }

  function hideMessage(selectedCards) {
    for (let i = 0; i < selectedCards.length; i++) {
      let msg = qs("#" + selectedCards[i].id + " p");
      selectedCards[i].removeChild(msg);
      selectedCards[i].classList.remove("hide-imgs");
      if (isASet(selectedCards)) {
        qs("#" + selectedCards[i].id).innerHTML = "";
        let divCards = qsa("#board div");
        let board = [];
        for (let i = 0; i < divCards.length; i++) {
          board.push(divCards[i].id);
        }

        while (board.includes(selectedCards[i].id) && board.length > 0) {
          selectedCards[i] = generateACard(generateRandomAttributes(easyDifficulty));
        }
        generateImages(generateRandomAttributes(easyDifficulty), selectedCards[i]);
      }
    }
  }



  /**
 * Checks to see if the three selected cards make up a valid set. This is done by comparing each
 * of the type of attribute against the other two cards. If each four attributes for each card are
 * either all the same or all different, then the cards make a set. If not, they do not make a set
 * @param {DOMList} selected - list of all selected cards to check if a set.
 * @return {boolean} true if valid set false otherwise.
 */
  function isASet(selected) {
    let attribute = [];
    for (let i = 0; i < selected.length; i++) {
      attribute.push(selected[i].id.split("-"));
    }
    for (let i = 0; i < attribute[0].length; i++) {
      let allSame = attribute[0][i] === attribute[1][i] &&
        attribute[1][i] === attribute[2][i];
      let allDiff = attribute[0][i] !== attribute[1][i] &&
        attribute[1][i] !== attribute[2][i] &&
        attribute[0][i] !== attribute[2][i];
      if (!(allSame || allDiff)) {
        return false;
      }
    }
    return true;
  }


  /**
   * Make sure to always add a descriptive comment above
   * every function detailing what it's purpose is
   * @param {variabletype} someVariable This is a description of someVariable, including, perhaps, preconditions.
   * @returns {returntype} A description of what this function is actually returning
   */
  function exampleFunction2(someVariable) {
    /* SOME CODE */
    return something;
  }

  /** ------------------------------ Helper Functions  ------------------------------ */
  /**
   * Note: You may use these in your code, but remember that your code should not have
   * unused functions. Remove this comment in your own code.
   */

  /**
   * Returns the element that has the ID attribute with the specified value.
   * @param {string} idName - element ID
   * @returns {object} DOM object associated with id.
   */
  function id(idName) {
    return document.getElementById(idName);
  }

  /**
   * Returns the first element that matches the given CSS selector.
   * @param {string} selector - CSS query selector.
   * @returns {object} The first DOM object matching the query.
   */
  function qs(selector) {
    return document.querySelector(selector);
  }

  /**
   * Returns the array of elements that match the given CSS selector.
   * @param {string} selector - CSS query selector
   * @returns {object[]} array of DOM objects matching the query.
   */
  function qsa(selector) {
    return document.querySelectorAll(selector);
  }

  /**
   * Returns a new element with the given tag name.
   * @param {string} tagName - HTML tag name for new DOM element.
   * @returns {object} New DOM object for given HTML tag.
   */
  function gen(tagName) {
    return document.createElement(tagName);
  }

})();
body, button, select, input {
  font-family: "Helvetica", "Verdana", sans-serif;
  text-align: center;
  font-size: 12pt;
}

main {
  width: 80%;
  margin: auto;
}

button, select {
  padding: 8px;
  background-color: white;
  border: 2pt solid black;
}

h2 {
  text-decoration: underline;
}

#start-btn {
  width: 100px;
  margin-top: 10px;
  margin-bottom: 20px;
}

#menu-view > article {
  background-color: #6F77ED;
  border-radius: 0.35em;
  border: 5pt solid black;
}

#menu-view > article, #details-bar {
  color: white;
}

.card, #details-bar, #board {
  display: flex;
  justify-content: space-evenly;
}

.card, #details-bar {
  align-items: center;
}

#details-bar {
  border-top-left-radius: 0.5em;
  border-top-right-radius: 0.5em;
  background-color: black;
  font-size: 14pt;
}

.card {
  width: 220px;
  height: 95px;
  border: 0.35em solid black;
  border-radius: 1em;
  cursor: pointer;
  margin-top: 5px;
  margin-bottom: 5px;
}

.card img {
  height: 85%;
}

.card p {
  font-weight: bold;
}

h2, .card p {
  font-size: 16pt;
}

.selected {
  box-shadow: #636363 6px 6px;
}

#board {
  border-right: black solid 5pt;
  border-left: black solid 5pt;
  border-bottom: black solid 5pt;
  padding: 20px;
  flex-wrap: wrap;
}

.hidden, .hide-imgs > img {
  display: none;
}
<html lang="en">

  <head>
    <meta charset="utf-8">
    <title>Set!</title>
    <link rel="stylesheet" href="set.css">
    <script src="set.js"></script>
  </head>

  <body>
    <header>
      <h1>Set!</h1>
    </header>

    <main>
      <section id="menu-view">
        <article>
          <h2>Choose a Timing Option:</h2>
          <select>
            <option value="60">1 Minute</option>
            <option value="180" selected>3 Minutes</option>
            <option value="300">5 Minutes</option>
          </select>

          <h2>Choose a Difficulty:</h2>
          <p>
            <label><input type="radio" name="diff" value="easy" checked> Easy</label>
            <label><input type="radio" name="diff" value="standard"> Standard</label>
          </p>

          <button id="start-btn">Start</button>
        </article>

        <section>
          <header>
            <h2>Rules</h2>
          </header>
          <p>
            Originally created by Marsha Jean Falco of Set Enterprises, Inc.,
            Set is a card game with a board of non-duplicate cards. There are two levels
            of difficulty for this game.
            In Standard
            Difficulty there are 4 different attributes (style, color, shape, and count) -
            each attribute can have one of three values. For example, shape can have 3
            values: "diamond", "oval", or "squiggle". In Easy Difficulty, all cards share a
            "solid" style attribute, so only the other 3 attributes can be different.
          </p>
          <p>
            A Set is a selection of 3 cards such that for each of attributes, all
            three cards have the same value or none of the cards have the same value.
            Your goal is to find as many Sets as you can on the board!
          </p>
          <p>Have fun!</p>
        </section>
      </section>

      <section id="game-view" class="hidden">
        <div id="details-bar">
          <button id="back-btn">Back to Main</button>
          <p><strong>Sets Found: </strong><span id="set-count">0</span></p>
          <p><strong>Time: </strong><span id="time">00:00</span></p>
          <button id="refresh-btn">Refresh Board</button>
        </div>
        <div id="board"></div>
      </section>
    </main>
  </body>

</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...