为什么在这种情况下使用循环?

时间:2020-04-26 17:09:31

标签: javascript

我有点困惑。考虑这种情况:我有一个复选框列表,每个复选框都有一个id,class和data-attribute(称为data-uid,它不等于复选框的ID)。

重点是检索单击的复选框data-uid属性。

因此,我在复选框父级上使用了JS click事件,以确定单击了哪个事件并获取其数据ID。

人们已经告诉我使用循环,直到得到我单击的复选框为止,就像这样(我本可以使用普通的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>

非常感谢您抽出宝贵的时间阅读和启发我。

汤姆

2 个答案:

答案 0 :(得分:0)

您的方法没有循环,绝对是最明智的方法。遍历所有复选框以查看每个复选框是否都是触发元素,这很杂乱,并破坏了事件和Event.target属性的整个目的。复杂度也会随着页面上复选框的数量而增加,无论使用多少个复选框,使用Event.target只需执行一项操作即可。

如您所提供的,

Event.target.getAttribute('data-uid')是实现所需行为的最直接方法。 =)

答案 1 :(得分:0)

听起来您只想在单击复选框时记录日志,而不是在单击任何其他元素时记录日志。如果您执行“ 具有复选框列表”,则需要测试单击的元素是否是这些复选框之一。惯用的方式是

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

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