为什么单击时我动态创建的html插入到最后一个循环的卡上

时间:2018-07-26 02:51:20

标签: javascript html

我试图更好地理解Javascript类。通过这样做,我可以动态创建玩家记分卡。有一个输入和提交按钮,可以创建任意数量的卡片。每个创建的卡还具有其自己的输入和提交框。当我在特定的卡片输入框中添加一个值并单击“提交”时,创建的内部html将转到最后创建的卡片,而不是当前的卡片。这是我的代码库的片段。同样,通过做一些研究(当然,我可能会误解),闭包和类(语法糖)在那里的方法https://medium.com/engineering-livestream/javascript-classes-vs-closures-cf6d6c1473f是不同的,因此不确定多数情况下闭包将如何起作用,因为大多数示例使用常规函数。

/*************************************************************************************************/

//Creates the Players score card

/*************************************************************************************************/
export default class CreateScoreCard {
    constructor()
    {
      this.plyCdCmplte = null;
      this.plyCardWrapper = null;
    }
  /*************************************************************************************************/
  createPlayerCardUpper()
  {
    let plyCdGrd,
      plyCdTtle,
      plyNm,
      plyScore,
      plyScTxtNd,
      plyNmTxtNd;

    this.plyCdCmplte = document.getElementById('player-card-complete');
    this.plyCardWrapper = document.createElement('div');
    this.plyCardWrapper.setAttribute('class', 'player-card-wrapper');

    plyCdGrd = document.createElement('div');
    plyCdTtle = document.createElement('div');
    plyNm = document.createElement('div');
    plyScore = document.createElement('div');

    plyCdGrd.setAttribute('class', 'player-card-grid');
    plyCdTtle.setAttribute('class', 'player-card-title');
    plyNm.setAttribute('class', 'player-name');
    plyNmTxtNd = document.createTextNode('Player One');
    plyNm.appendChild(plyNmTxtNd);
    plyScore.setAttribute('class', 'player-score');
    plyScTxtNd = document.createTextNode('0');
    plyScore.appendChild(plyScTxtNd);

    this.plyCdCmplte.appendChild(this.plyCardWrapper);
    this.plyCardWrapper.appendChild(plyCdGrd);
    plyCdGrd.appendChild(plyCdTtle);
    plyCdTtle.appendChild(plyNm);
    plyCdTtle.appendChild(plyScore);
  }
  /*************************************************************************************************/
  createPlayerCardMid()
  {
      let sttngsGrd,
      sttngsCntr,
      sttngsBrs,
      frmDvPnts,
      pntsBtnTxtNd;

      sttngsGrd = document.createElement('div');
      sttngsGrd.setAttribute('class', 'settings-grid');
      sttngsCntr = document.createElement('div');
      sttngsCntr.setAttribute('class', 'settings-container');
      sttngsBrs = document.createElement('i');
      sttngsBrs.setAttribute('class', 'fas fa-bars settings-bars');
      frmDvPnts = document.createElement('div');
      frmDvPnts.setAttribute('class', 'form-div-points');
      this.inptPts = document.createElement('input');
      this.inptPts.type = 'number';
      this.inptPts.min = '1';
      this.inptPts.value = '1';
      this.inptPts.setAttribute ('class', 'input-points')
      this.pntsBtn = document.createElement('button');
      this.pntsBtn.setAttribute('class', 'points-btn');
      pntsBtnTxtNd = document.createTextNode('ADD');
      this.pntsBtn.appendChild(pntsBtnTxtNd);

      this.plyCardWrapper.appendChild(sttngsGrd);
      sttngsGrd.appendChild(sttngsCntr);
      sttngsCntr.appendChild(sttngsBrs);
      sttngsGrd.appendChild(frmDvPnts);
      frmDvPnts.appendChild(this.inptPts);
      frmDvPnts.appendChild(this.pntsBtn);    
  }
  /*************************************************************************************************/
  createPlayerCardLower()
  {
      this.plyCdBdy = document.createElement('div');
      this.plyCdBdy.setAttribute('class', 'player-card-body');
      this.plyCardWrapper.appendChild(this.plyCdBdy);
  }
  /*************************************************************************************************/
  getPlayerScoreFromUserInput()
  {
      let pointsBtn = document.getElementsByClassName('points-btn');
      let inputPoints = document.getElementsByClassName('input-points');

      let playerCardBody = document.getElementsByClassName('player-card-body');

        for(let i = 0; i < playerCardBody.length; i++)
      {
          let numFromInptArr = [];
          let sumOfUserInputNums;

          pointsBtn[i].addEventListener('click', ()=> 
          {
              inputPoints[i].value;

              numFromInptArr.push(+inputPoints[i].value)

              sumOfUserInputNums = numFromInptArr.reduce((a, b)=>a+b);

              this.playerScore = document.getElementsByClassName('player-score');

              this.playerScore[i].innerHTML = sumOfUserInputNums;

              this.createRoundScoreHtml(1, inputPoints[i].value)
          })
      }  

      // This is the forEach method of looping through eventListener's
     /*  Object.keys(pointsBtn).forEach(function (key){
          pointsBtn[key].addEventListener('click', ()=> {
              console.log(inputPoints[key].value);
          })
      }); */
  }
  /*************************************************************************************************/
  createRoundScoreHtml(roundNum, roundScore)
  {
      // Using this method to create the html content
      this.plyCdBdy.insertAdjacentHTML("beforeend", 
          `<div class = "round-container">
          <span class = "round-text">
          Round
          <span class = "round-number">
          ${roundNum}
          <span class="score-text">Score</span>
          </span>
          </span>
          <span class = "round-score">${roundScore}</span></div>`);
  }
  /*************************************************************************************************/
  getNumOfPlayers()
  {
       this.numOfPlayersInput = document.getElementById('num-players-input');
       this.numPlayersSubmitBtn = document.getElementById('num-players-submit-btn');
       this.numPlayersCntnr = document.getElementById('num-players-cntnr');

      // When user updates the input form with a num and then clicks
      // on the submit btn, will iterate the amount of players
      this.numPlayersSubmitBtn.addEventListener('click', (event) =>
      {
          event.preventDefault();

          // Clears the card from the html 
          if (this.plyCdCmplte !== null)
          {
              this.plyCdCmplte.innerHTML = '';
          }

          // Number of players submitted from the number of players input box
          for(let iterPlayers = 0; iterPlayers < this.numOfPlayersInput.value; iterPlayers++)
          {
              this.createPlayerCardUpper();
              this.createPlayerCardMid();
              this.createPlayerCardLower();
          }
          this.getPlayerScoreFromUserInput();

      })
  }
  /*************************************************************************************************/
  }

1 个答案:

答案 0 :(得分:0)

新添加的分数进入最后创建的卡片的原因是以下声明

this.playerScore = document.getElementsByClassName('player-score')
this.playerScore[i].innerHTML = sumOfUserInputNums;

存在此问题

  1. document.getElementsByClassName返回一个数组,其中包含具有匹配的className的所有元素。看到您的示例,您将拥有很多这些要素。考虑使用id或在className本身上添加一些标识符令牌,例如score3-player1
  2. this.playerScore[i]我不会与您的期望保持一致,因为添加新卡时阵列项会随着时间而变化。 getElementsByClassName返回的集合中的元素按照它们在源代码中出现的顺序进行排序。 [Src <-W3Schools]

看看我的答案,该答案涉及如何定位某些HTML元素的关联Array元素索引,以帮助您更好地定位卡片:https://stackoverflow.com/a/51560133/5642455