【问题标题】:Attach event listener through javascript to radio button通过javascript将事件监听器附加到单选按钮
【发布时间】:2012-01-19 06:39:07
【问题描述】:

我有几个同名的单选按钮。像这样:

<form name="formA">
<input type="radio" name="myradio" value="A"/>
<input type="radio" name="myradio" value="B"/>
<input type="radio" name="myradio" value="C"/>
<input type="radio" name="myradio" value="D"/>
</form>

现在我必须通过 javascript 向所有单选按钮添加事件侦听器。如果下面的伪代码是错误的,那么请告诉我怎么做-

var radios = document.forms["formA"].elements["myradio"];
  for(radio in radios) {
    radio.onclick = function() {
        alert(radio.value);
    }
}

【问题讨论】:

    标签: javascript html dom


    【解决方案1】:

    JavaScript 中的 For in 循环返回键,而不是值。要让 for in 循环正常工作,假设您没有向数组添加自定义属性,您可以这样做:

    for(radio in radios) {
        radios[radio].onclick = function() {
            alert(this.value);
        }
    }
    

    但您应该始终使用常规 for 循环来循环数组,以避免意外包含自定义添加的可枚举属性:

    var radios = document.forms["formA"].elements["myradio"];
    for(var i = 0, max = radios.length; i < max; i++) {
        radios[i].onclick = function() {
            alert(this.value);
        }
    }
    

    【讨论】:

    • 为什么要“总是用常规的 for 循环来循环数组”?
    • @ojrask - 旧答案,但基本上自定义添加的属性,如果添加,可以迭代。但是当然有了 ES6,现在你有了一个 for of 循环,你可以使用数组或任何可迭代对象。
    • 啊,是的,我明白了。没想到。也许编辑答案以详细说明? :)
    【解决方案2】:

    另一种选择是使用delegated handlersattach multiple elements to a single event listener

    您可以将父侦听器附加到document 或任何适当的父节点。然后,您可以使用 Element.matches() API 或 event.target 上的任何内容检查相应目标是否引发了事件

    document.getElementById("languages").addEventListener('click', function (event) {
        if (event.target && event.target.matches("input[type='radio']")) {
            // do something here ...
        }
    });
    

    这大致相当于以下使用.on() 提供委托的jQuery 语法

    $("#languages").on("click", "input[type='radio']", function(event) {
        // do something here ...
    });
    

    如果你想扩展EventTarget.addEventListener()原型,你可以用你自己的方法包装:

    window.EventTarget.prototype.addDelegatedListener = function(type, delegateSelector, listener) {
        this.addEventListener(type, function (event) {
            if (event.target && event.target.matches(delegateSelector)) {
                listener.call(event.target, event)
            }
        });
    }
    

    然后像这样使用:

    document.addDelegatedListener("click", "input[type='radio']", function(event) {
        // do something here ...
    });
    

    堆栈片段中的演示

    // example 1 - regular add event listener
    document.getElementById("languages").addEventListener('click', function (event) {
        if ( event.target && event.target.matches("input[type='radio']") ) {
            console.log(event.target.value)
        }
    });
    
    // example 2 - reusable delegated listener
    window.EventTarget.prototype.addDelegatedListener = function(type, delegateSelector, listener) {
        this.addEventListener(type, function (event) {
            if (event.target && event.target.matches(delegateSelector)) {
                listener.call(event.target, event)
            }
        });
    }
    
    let parent = document.getElementById("weekdays")
    parent.addDelegatedListener("click", "input[type='radio']", function(event) {
        console.log(this.value)
    });
    h3 {
        margin-top: 20px;
        margin-bottom: 10px;
        font-size: 1.1em;
    }
    code {
        background: #e9e9e9;
        padding: 1px 4px;
        border-radius: 3px;
    }
    label input {
        vertical-align: text-top;
    }
    <h3>Languages <code>addEventListener</code> + <code>Element.matches</code></h3>
    <div id="languages">
      <label><input type="radio" name="languages" value="HTML"> HTML </label>
      <label><input type="radio" name="languages" value="JS"> JS </label>
      <label><input type="radio" name="languages" value="CSS"> CSS </label>
    </div>
    
    <h3>Weekdays <code>EventTarget.prototype.addDelegatedListener</code></h3>
    <div id="weekdays">
      <label><input type="radio" name="days" value="Mon"> Mon </label>
      <label><input type="radio" name="days" value="Tue"> Tue </label>
      <label><input type="radio" name="days" value="Wed"> Wed </label>
    </div>

    【讨论】:

      【解决方案3】:

      您可以只添加一个侦听器来侦听所有单选按钮,而不是添加单个侦听器。

      使用 jquery,你可以这样做

      $(document).ready(function(){
          $('input[type=radio]').click(function(){
              alert(this.value);
          });
      });
      

      Demo

      仅适用于 ID 为 formA 的表单中的收音机

       $(document).ready(function(){
              $('#formA input[type=radio]').click(function(){
                  alert(this.value);
              });
          });
      

      仅适用于 ID 为 myradio 的收音机

      $(document).ready(function(){
          $('input[type=radio]').click(function(){
              if (this.id == "myradio")
                  alert(this.value);
          });
      });
      

      Demo

      【讨论】:

      • 1.我需要纯 JavaScript 代码。 2. 我只想将事件监听器附加到那些名称属性设置为“myradio”(考虑)的收音机。但我认为上面的代码会将函数附加到整个文档中的所有收音机。 :(
      • @BigFatPig 你可以让它只附加到特定表单中的收音机,甚至是具有特定 id 的收音机
      【解决方案4】:

      一个好的开始,但不要以这种方式使用 for..,因为它会遍历所有可枚举的属性,而且您还没有检查它们是否都表示元素。

      最好使用索引:

      for (var i=0, iLen=radios.length; i<iLen; i++) {
        radios[i].onclick = function() {...};
      } 
      

      【讨论】:

        【解决方案5】:
        for(var property in object) { ... } 
        

        用于循环对象以查找属性。 对于数组,您可以使用普通的 for 循环

        for(var i=0; i< radios.length; i++) {
             var radio = radios[i];
             ....
        } 
        

        【讨论】:

          【解决方案6】:

          试试这个:

          var radioButtonSection = document.getElementsByName('eazi_auto_loan_option');for (var i = 0; i < radioButtonSection.length; i++) {
              radioButtonSection[i].onclick = function() {
                  console.log(this.value);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-08-04
            • 1970-01-01
            • 2012-11-11
            • 1970-01-01
            • 2012-12-21
            • 1970-01-01
            • 2012-02-07
            • 1970-01-01
            相关资源
            最近更新 更多