如何从祖父div中删除一个类

时间:2017-09-16 09:44:03

标签: javascript

我有这样的代码。它只是为了展示它是如何工作的。当我想要比较卡时出现问题。当我点击第一张和第二张卡并且它们不匹配时,他们的祖父div应该移除一个翻转瓦片的类。第二件事,我点击同一张卡两次,它将返回" win"。如何解决这个问题并使这段代码看起来干净?



{
  let guesses = [];
  let tries = 0;
  const doubleArrVal = arr => arr.concat(arr);
  const addFlipEffect = (e) => {
    let target = e.currentTarget;
    if (!target.classList.contains("tile--static")) {
      target.classList.add("tile--active");
    }
    return target;
  };
  const addManyListeners = (collection, e, fn) => {
    for (let i = 0; i < collection.length; i++) {
      collection[i].addEventListener(e, fn, false);
    }
  };
  const randomize = (arr) => {
    for (let i = 0; i < arr.length; i++) {
      const j = Math.floor(Math.random() * (i + 1));
      const tmp = arr[i];
      arr[i] = arr[j];
      arr[j] = tmp;
    }
    return arr;
  };
  const prepareArray = (ammount) => {
    let imgNames = ["angular", "bootstrap", "css", "foundation", "github", "grunt", "html", "ruby", "jquery", "less", "nodejs", "sass"];
    imgNames = imgNames.slice(0, ammount);
    const doubled = doubleArrVal(imgNames);
    return randomize(doubled);
  };
  const createMarkUp = (id) => {
    const markUp = `<div class="tile  tile--game">
      <div class="tile__side  tile__side--front">
      </div>
      <div class="tile__side  tile__side--back">
        <img src="img/${id}.svg" alt="${id}" class="tile__img" data-name="${id}">
      </div>
    </div>`;
    return markUp;
  };
  const createCards = (ammount) => {
    const container = document.getElementById("gameContainer");
    const preparedCards = prepareArray(ammount);
    preparedCards.map(card => {
      const cardElement = createMarkUp(card);
      container.innerHTML += cardElement;
    });
    return container;
  };
  // Problem is here 
  const compare = (e) => {
    const userPick = e.currentTarget;
    let image = userPick.querySelector("[data-name]");
    guesses.push(image);
    tries++;
    if (tries === 2) {
      if (guesses[0].dataset.name === guesses[1].dataset.name) {
        console.log("win");
      } else {
        setTimeout(() => {
          guesses[0].parentNode.parentNode.classList.remove("tile--active");
          guesses[1].parentNode.parentNode.classList.remove("tile--active");
        }, 500);
      }
      guesses = [];
      tries = 0;
    }
  }
  const startGame = (level) => {
    const gameCards = createCards(4);
    addManyListeners(gameCards.children, "click", addFlipEffect);
    addManyListeners(gameCards.children, "click", compare);
  };
  startGame();
}
&#13;
<div id ="gameContainer"></div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

这是范围错误。您的超时使用变量guesses,但它在全局范围内执行,其中变量未定义。所以我使用bind来将它绑定到函数。

为了确保猜测中有2个不同的元素,只需在测试它们之前测试它们。

{
  let guesses = [];
  let tries = 0;
  const doubleArrVal = arr => arr.concat(arr);
  const addFlipEffect = (e) => {
    let target = e.currentTarget;
    if (!target.classList.contains("tile--static")) {
      target.classList.add("tile--active");
    }
    return target;
  };
  const addManyListeners = (collection, e, fn) => {
    for (let i = 0; i < collection.length; i++) {
      collection[i].addEventListener(e, fn, false);
    }
  };
  const randomize = (arr) => {
    for (let i = 0; i < arr.length; i++) {
      const j = Math.floor(Math.random() * (i + 1));
      const tmp = arr[i];
      arr[i] = arr[j];
      arr[j] = tmp;
    }
    return arr;
  };
  const prepareArray = (ammount) => {
    let imgNames = ["angular", "bootstrap", "css", "foundation", "github", "grunt", "html", "ruby", "jquery", "less", "nodejs", "sass"];
    imgNames = imgNames.slice(0, ammount);
    const doubled = doubleArrVal(imgNames);
    return randomize(doubled);
  };
  const createMarkUp = (id) => {
    const markUp = `<div class="tile  tile--game">
      <div class="tile__side  tile__side--front">
      </div>
      <div class="tile__side  tile__side--back">
        <img src="img/${id}.svg" alt="${id}" class="tile__img" data-name="${id}">
      </div>
    </div>`;
    return markUp;
  };
  const createCards = (ammount) => {
    const container = document.getElementById("gameContainer");
    const preparedCards = prepareArray(ammount);
    preparedCards.map(card => {
      const cardElement = createMarkUp(card);
      container.innerHTML += cardElement;
    });
    return container;
  };
  const compare = (e) => {
    const userPick = e.currentTarget;
    let image = userPick.querySelector("[data-name]");
    guesses.push(image);
    tries++;
    if (tries === 2) {
      if (guesses[0] !== guesses[1] && guesses[0].dataset.name === guesses[1].dataset.name) {
        console.log("win");
      } else {
        setTimeout(((guesses) => {
          guesses[0].parentNode.parentNode.classList.remove("tile--active");
          guesses[1].parentNode.parentNode.classList.remove("tile--active");
        }).bind(null, guesses), 500);
      }
      guesses = [];
      tries = 0;
    }
  }
  const startGame = (level) => {
    const gameCards = createCards(4);
    addManyListeners(gameCards.children, "click", addFlipEffect);
    addManyListeners(gameCards.children, "click", compare);
  };
  startGame();
}
<div id="gameContainer"></div>

答案 1 :(得分:1)

我会使用guesses的Set来促进唯一选择:

  let guesses = new Set;

  //...

  const compare = (e) => {
    const userPick = e.currentTarget;
    let image = userPick.querySelector("[data-name]");
    guesses.add(image);
    if (guesses.size === 2) { // guaranteed to be 2 different images
      if (new Set(Array.from(guesses, guess => guess.dataset.name)).size == 1) {
        console.log("win");
        guesses = new Set;
      } else {
        setTimeout(() => {
          for (let guess of guesses) {
            guess.parentNode.parentNode.classList.remove("tile--active");
          }
          guesses = new Set; // only clear here
        }, 500);
      }
    }
  }

如果您的模板将data-name="${id}"放在祖父/根div上,那么这一切都会变得更简单:那么您只需使用div,而不是{ {1}}:

img