如何迭代节点列表以便为每个元素节点分配特定于索引的事件处理程序?

问题描述 投票:0回答:3

我正在尝试使用 for 循环来递增多个按钮元素,以便我可以为它们分配不同的操作。

我无法弄清楚这一点,这是代码。

我对 javascript 非常陌生,我已经阅读了 MDN 文档,但没有提出任何建议。

let numberOfbuttons = document.querySelectorAll(".numbers");

for (i = 0; i < numberOfbuttons; i++) {
  document.querySelectorAll(".numbers")[i].addEventListener("click", function() {
    document.querySelector(".result").innerHTML = "1"
  })
};
body {
  background-color: blanchedalmond;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
}

.Calc {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
  grid-area: 2/2;
}

button[value="0"] {
  grid-area: 5/2/5/2;
}

button {
  background-color: aliceblue;
  color: black;
}

button[value="AC"] {
  grid-area: 5/1;
}

button[value="+"] {
  grid-area: 3/4;
}

button[value="-"] {
  grid-area: 2/4;
}

.result {
  grid-area: 1/1/1/5;
  background-color: #CBD2A4;
  text-align: center;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8" />
  <title>Calculator</title>
  <link rel="stylesheet" href="styles.css" />
  <link href="https://fonts.googleapis.com/css?family=Arvo" rel="stylesheet" />
</head>

<body>
  <div class="Calc">
    <div class="result">
      <p>Type in your "numbers"</p>
    </div>

    <button class="numbers">1</button>
    <button class="numbers">2</button>
    <button class="numbers">3</button>
    <button class="numbers">4</button>
    <button class="numbers">5</button>
    <button class="numbers">6</button>
    <button class="numbers">7</button>
    <button class="numbers">8</button>
    <button class="numbers">9</button>
    <button class="numbers">0</button>
    <button value="AC">AC</button>
    <button value="+">+</button>
    <button value="-">-</button>
    <button value="*">x</button>
    <button value="/">/</button>
    <button value="=">=</button>
  </div>
  <script src="index.js" charset="utf-8"></script>
</body>

</html>

javascript event-handling addeventlistener nodelist event-delegation
3个回答
0
投票

你就快到了。

querySelector
返回一个列表,而不是其长度。你可以试试这个:

let buttons = document.querySelectorAll(".numbers");

for(i = 0; i < buttons.length; i++){
  buttons[i].addEventListener("click",function(){
document.querySelector(".result").innerHTML= "1"
  })
};
body {
    background-color: blanchedalmond;
    display:grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr;
}
.Calc{
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
    grid-area: 2/2;
}
button[value="0"]{
    grid-area: 5/2/5/2;
}
button{
    background-color: aliceblue;
    color: black;
}
button[value="AC"]{
    grid-area:5/1;
}
button[value="+"]{
    grid-area: 3/4;
}
button[value="-"]{
    grid-area: 2/4;
}
.result{
    grid-area: 1/1/1/5;
    background-color: #CBD2A4;
    text-align:center;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8" />
    <title>Calculator</title>
    <link rel="stylesheet" href="styles.css" />
    <link
      href="https://fonts.googleapis.com/css?family=Arvo"
      rel="stylesheet"
    />
  </head>

  <body>
    <div class="Calc">
      <div class="result"><p>Type in your "numbers"</p></div>

      <button class="numbers" >1</button>
      <button class="numbers" >2</button>
      <button class="numbers" >3</button>
      <button class="numbers" >4</button>
      <button class="numbers" >5</button>
      <button class="numbers" >6</button>
      <button class="numbers" >7</button>
      <button class="numbers" >8</button>
      <button class="numbers" >9</button>
      <button class="numbers" >0</button>
      <button value="AC">AC</button>
      <button value="+">+</button>
      <button value="-">-</button>
      <button value="*">x</button>
      <button value="/">/</button>
      <button value="=">=</button>
    </div>
    <script src="index.js" charset="utf-8"></script>
  </body>
</html>


0
投票

OP是否意识到

querySelectorAll
实际上返回一个非活动的
NodeList
,它有自己的
forEach
方法来迭代其每个元素节点?

但无论如何,永远不会为每个元素节点注册一个事件侦听器,每个元素节点都有其自定义的处理程序函数,由元素的索引确定。

一个人宁愿通过对所有刻度盘进行分组并利用事件委托来稍微改进HTML结构。

因此,我们实现了一个处理每个旋转按钮单击事件的函数。然后,该处理程序在所有拨号按钮的最近父元素处注册一次。

function handleCalculatorDialClick(evt) {

  const target = evt.target.closest('button');
  const { value } = target;

  const isSingleDigitDial = (/\d/).test(value);

  if (isSingleDigitDial) {
    target

      .closest('.calculator')
      .querySelector('output')
      .value = value;

  } /* else if () {

    // handle another dial

  }*/
}
document
  .querySelector('.calculator .dials')
  ?.addEventListener('click', handleCalculatorDialClick);
body {
  margin: 0;
}
.calculator {

  display: grid;
  grid-template-rows: repeat(5, 1fr);
  grid-template-columns: repeat(4, 1fr);
  width: 45%;

  button {
    color: black;
    background-color: #fffaf0;

    &:focus {
      z-index: 1;
      outline: 2px solid lime;
    }
  }

  .display {
    grid-area: 1 / 1 / 1 / 4;

    background-color: #CBD2A4;
    padding: .95em;
    text-align:center;
  }

  .dials {
    grid-area: 2 / 1 / 5 / 4;

    display: grid;
    grid-template-rows: repeat(4, 1fr);
    grid-template-columns: repeat(4, 1fr);

    .non-zero-digits {
      grid-area: 1 / 1 / 4 / 4;

      display: grid;
      grid-template-rows: repeat(3, 1fr);
      grid-template-columns: repeat(3, 1fr);

      button {
        background-color: aliceblue;
      }
    }
    .linear {
      grid-area: 1 / 4 / 3 / 4;

      display: grid;
      grid-template-rows: repeat(2, 1fr);
      grid-template-columns: repeat(1, 1fr);
    }
    .geometric {
      grid-area: 4 / 2 / 4 / 4;

      display: grid;
      grid-template-rows: repeat(1, 1fr);
      grid-template-columns: repeat(2, 1fr);
    }
    button[value="0"] {
      grid-area: 3 / 4;

      background-color: aliceblue;
    }
    button[value="="] {
      grid-area: 4 / 4;

      background-color: #ffebc5;
    }
    button[value="AC"] {
      grid-area: 4 / 1;

      background-color: #ffd88c;
    }
  } 
}
<link href="https://fonts.googleapis.com/css?family=Arvo" rel="stylesheet" />

<div class="calculator">
  <output class="display">
   Type in your "numbers"
  </output>

  <div class="dials">
    <div class="non-zero-digits">
      <button value="1">1</button>
      <button value="2">2</button>
      <button value="3">3</button>
      <button value="4">4</button>
      <button value="5">5</button>
      <button value="6">6</button>
      <button value="7">7</button>
      <button value="8">8</button>
      <button value="9">9</button>
    </div>
    <button value="0">0</button>

    <div class="linear">
      <button value="+">+</button>
      <button value="-">-</button>
    </div>
    <div class="geometric">
      <button value="*">x</button>
      <button value="/">/</button>
    </div>

    <button value="=">=</button>
    <button value="AC">AC</button>  
  </div>
</div>


-1
投票

作为练习,我使代码更加完整,并稍微改变了方法(以显示实现相同结果的另一种方法)并添加了一些东西。

const numericButtons = document.querySelectorAll(".numbers");
const resultDisplay = document.querySelector(".result");
const originalDisplay = resultDisplay.textContent;

for ( aButton of numericButtons )
{
  aButton.addEventListener
  (
    "click", clickEvent =>
    {
      if ( resultDisplay.textContent == originalDisplay )
      {
        resultDisplay.textContent = '';
      }
      
      // The `result` class content receives the button content additionally.
      resultDisplay.textContent += clickEvent.target.textContent;
    }
  )
};

// Just adding the behaviour of the `AC` button.
document.querySelector("[value=AC]").addEventListener
(
  "click", clickEvent =>
  {
    resultDisplay.textContent = originalDisplay;
  }
);
body {
    background-color: blanchedalmond;
    display:grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr;
}
.Calc{
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
    grid-area: 2/2;
}
button[value="0"]{
    grid-area: 5/2/5/2;
}
button{
    background-color: aliceblue;
    color: black;
}
button[value="AC"]{
    grid-area:5/1;
}
button[value="+"]{
    grid-area: 3/4;
}
button[value="-"]{
    grid-area: 2/4;
}
.result{
    grid-area: 1/1/1/5;
    background-color: #CBD2A4;
    text-align:center;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8" />
    <title>Calculator</title>
    <link rel="stylesheet" href="styles.css" />
    <link
      href="https://fonts.googleapis.com/css?family=Arvo"
      rel="stylesheet"
    />
  </head>

  <body>
    <div class="Calc">
      <div class="result"><p>Type in your "numbers"</p></div>

      <button class="numbers" >1</button>
      <button class="numbers" >2</button>
      <button class="numbers" >3</button>
      <button class="numbers" >4</button>
      <button class="numbers" >5</button>
      <button class="numbers" >6</button>
      <button class="numbers" >7</button>
      <button class="numbers" >8</button>
      <button class="numbers" >9</button>
      <button class="numbers" >0</button>
      <button value="AC">AC</button>
      <button value="+">+</button>
      <button value="-">-</button>
      <button value="*">x</button>
      <button value="/">/</button>
      <button value="=">=</button>
    </div>
    <script src="index.js" charset="utf-8"></script>
  </body>
</html>

© www.soinside.com 2019 - 2024. All rights reserved.