首页 > 解决方案 > 为什么在这种情况下使用循环?

问题描述

我有点困惑。考虑这种情况:我有一个复选框列表,每个复选框都有一个 id、类和数据属性(称为 data-uid,它不等于复选框 id)。

关键是要检索单击的复选框 data-uid 属性。

因此,我在复选框父级上使用 JS 单击事件来确定单击了哪一个并获取其 data-uid。

人们告诉我要使用循环,直到我点击了复选框,就像这样(我可以使用普通的 for 循环,但你明白了):

const checkboxArray = [...document.getElementsByTagName('input')];

document.addEventListener('click', event => {
    checkboxArray.find(element => {
        if (event.target === element) {
            console.log(element.getAttribute('data-uid'));
        }
    });
});

但是,为什么不这样做,没有任何循环呢?

document.addEventListener('click', event => {
    if (event.target.getAttribute('data-uid')) {
        console.log(event.target.getAttribute('data-uid'));
    }
});

这两种方法返回预期的结果:单击复选框的 data-uid 属性。但是,哪一个最好用,为什么?正如我之前所说,人们总是告诉我使用循环,但如果你可以避免它,为什么?

这是一个片段,可以看到它的实际效果:

const method1 = document.getElementById('method1');
const method2 = document.getElementById('method2');

const output1 = document.getElementById('output1');
const output2 = document.getElementById('output2');

method1.addEventListener('click', event => { 
  const checkboxArray = [...document.getElementsByClassName('checkbox')];
  
  checkboxArray.find(element => {
  	if (event.target === element) {
  		output1.innerHTML += `${element.getAttribute('data-uid')} `;
  	}
  });
});

method2.addEventListener('click', event => {
	if (event.target.getAttribute('data-uid')) {
  	output2.innerHTML += `${event.target.getAttribute('data-uid')} `;
  }
});
<div id="method1">
  <p><strong>Method 1 : Using a loop</strong></p>
  <label for="1">1</label>
  <input type="checkbox" data-uid="a1" class="checkbox">
  <label for="2">2</label>
  <input type="checkbox" id="2" data-uid="b2" class="checkbox">
  <label for="3">3</label>
  <input type="checkbox" id="3" data-uid="c3" class="checkbox">
</div>

<div id="output1">Data uid : </div>

<br>

<div id="method2">
  <p><strong>Method 2 : Not using a loop</strong></p>
   <label for="4">4</label>
  <input type="checkbox" id="4" data-uid="d4" class="checkbox">
  <label for="5">5</label>
  <input type="checkbox" id="5" data-uid="e5" class="checkbox">
  <label for="6">6</label>
  <input type="checkbox" id="6" data-uid="f6" class="checkbox">
</div>


<div id="output2">Data uid : </div>

非常感谢您花时间阅读和启发我。

汤姆

标签: javascript

解决方案


听起来您只想在单击复选框时记录事情,而不是在单击任何其他元素时。如果您确实“有一个复选框列表”,那么您需要测试单击的元素是否是这些复选框之一。这样做的惯用方式是

document.addEventListener('click', event => {
    if (checkboxArray.includes(event.target)) {
        console.log(event.target.getAttribute('data-uid'));
    }
});

当然,如果您没有列表/数组,但有一些其他条件(例如“是复选框输入”或“具有data-uid属性”),那么请确保您也可以使用这些条件来确定是否要处理事件。但是代码做了一些不同的事情,并且会触发具有该属性的任何元素,而不仅仅是列表中的输入。您需要保证只有那些具有此属性,以确保这两种方法是等效的。


推荐阅读