如何在纯Javascript中使用addEventListener监听单选按钮?

13

如何在HTML中为单选按钮添加事件监听器?考虑以下表单:

<label>
    <input name="contract_duration" type="radio" value="6-Months" {{ $contract && $contract->contract_duration === '6-Months' ? 'checked' : ''  }} />
    <span>6-Months</span>
</label>

<label>
    <input name="contract_duration" type="radio" value="1-Year" {{ $contract && $contract->contract_duration === '1-Year' ? 'checked' : ''  }} />
    <span>1-Year</span>
</label>

<label>
    <input name="contract_duration" type="radio" value="2-Years" {{ $contract && $contract->contract_duration === '2-Years' ? 'checked' : ''  }} />
    <span>2-Years</span>
</label>

这是我的JavaScript代码:

if(document.querySelector('input[name="contract_duration"]')){
    document.querySelector('input[name="contract_duration"]').addEventListener("click", function(){
        var item = document.querySelector('input[name="contract_duration"]').value;
        console.log(item);
    });
}

执行程序时,我的代码只记录第一个,即6-Months,其他的如果点击则不显示。


2
document.querySelector('input[name="contract_duration"]') 是第一个。使用事件委托代替它。监听所有三个单选按钮的父元素上的 change 事件,然后使用事件参数的 target 属性来确定哪个单选按钮发生了变化。 - Sebastian Simon
你需要监听 change 事件而不是 click 事件。输入框不使用任何 "click",在这方面点击并不重要。 - vsync
3个回答

22

querySelector函数只返回选择器匹配的所有元素中的第一个元素,因此出现了问题。您需要改用querySelectorAll,这将返回所有匹配的元素,然后您可以循环遍历它们以为每个元素添加事件侦听器。

此外,在这种情况下最佳做法是监听“change”事件,而不是“click”事件,这样当用户单击已选择的单选按钮时不会不必要地触发事件。

演示:

if (document.querySelector('input[name="contract_duration"]')) {
  document.querySelectorAll('input[name="contract_duration"]').forEach((elem) => {
    elem.addEventListener("change", function(event) {
      var item = event.target.value;
      console.log(item);
    });
  });
}
<label>
    <input name="contract_duration" type="radio" value="6-Months" checked />
    <span>6-Months</span>
</label>

<label>
    <input name="contract_duration" type="radio" value="1-Year" />
    <span>1-Year</span>
</label>

<label>
    <input name="contract_duration" type="radio" value="2-Years" />
    <span>2-Years</span>
</label>


6
你需要使用querySelectorAll,它返回一个元素列表。
change事件仅针对选定的单选框运行。

let contact = document.querySelectorAll('input[name="contract_duration"]');
                                  // or '.your_radio_class_name'

for (let i = 0; i < contact.length; i++) {
  contact[i].addEventListener("change", function() {
    let val = this.value; // this == the clicked radio,
    console.log(val);
  });
}
label {
  display: block;
}
<label>
  <input name="contract_duration" type="radio" value="6-Months"/>
  <span>6-Months</span>
</label>

<label>
  <input name="contract_duration" type="radio" value="1-Year"/>
  <span>1-Year</span>
</label>

<label>
  <input name="contract_duration" type="radio" value="2-Years"/>
  <span>2-Years</span>
</label>


1
你的代码问题在于querySelector仅返回第一个匹配的元素。如果你想要所有元素都有事件监听器,应该使用querySelectorAll并循环遍历元素。
像这样:
if(document.querySelector('input[name="contract_duration"]')){
    document.querySelectorAll('input[name="contract_duration"]').forEach((elem) => {
        elem.addEventListener("click", function(event){
            var item = event.target.value;
            console.log(item);
        });
    });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接