草庐IT

javascript - 为什么点击我动态创建的 html 被插入到最后一张循环卡上

coder 2023-08-12 原文

我试图更好地理解 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();

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

最佳答案

之所以新添加的分数去到上次创建的卡中是下面的语句

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

问题:

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

看看我的一个答案,它谈到定位某些 HTML 元素的关联数组元素索引以帮助您更好地定位您的卡片:https://stackoverflow.com/a/51560133/5642455

关于javascript - 为什么点击我动态创建的 html 被插入到最后一张循环卡上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51530299/

有关javascript - 为什么点击我动态创建的 html 被插入到最后一张循环卡上的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  5. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  6. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  7. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  8. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  9. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  10. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

随机推荐