【问题标题】:addEventListener on programatically created checkbox not working以编程方式创建的复选框上的 addEventListener 不起作用
【发布时间】:2018-05-27 17:19:42
【问题描述】:

我创建了一个函数,它接受select multiple 输入并根据此选择的选项生成复选框。然后,我希望每个复选框在单击时执行一些操作。功能是:

const makeCheckboxDropdown = (input) => {
    if (input.type !== "select-multiple") {
        console.error("The input must be an `select multiple` type!")
        return
    }

    input.options[0].selected = false

    const header = document.getElementById('header')
    const outer = document.createElement('div')
    const options = input.options
    for (i = 0; i < options.length; i++) {
        let div = document.createElement('div')
        div.classList.add('checkbox')

        let label = document.createElement('label')

        let cb = document.createElement('input')
        cb.type = "checkbox"
        cb.value = options[i].value
        cb.addEventListener("change", (e) => console.log("clicked"))

        label.appendChild(cb)
        label.innerHTML += options[i].value

        div.appendChild(label)
        outer.appendChild(div)
    }
    header.parentNode.insertBefore(outer, header.nextSibiling)
}

一切正常:复选框按预期生成。除此之外,当我单击复选框时,什么也没有发生。它应该在控制台上记录“点击”,但没有任何反应。奇怪的是,如果我通过浏览器调试控制台添加相同的 EventListener,它就可以工作。

这里发生了什么?

编辑:repl.it 示例。

【问题讨论】:

    标签: javascript events checkbox addeventlistener


    【解决方案1】:

    这是您在添加复选框后在标签上使用innerHTML 的问题。一种可行的替代方法是稍作修改,如下所示。我所做的是将另一个元素(一个跨度,您也可以使用document.createTextNode)附加到该值。此操作是安全的,因为我没有在其中包含复选框的元素上使用 innerHTML

    innerHTML 在做什么的解释可以在这个问题here 中看到。

    我相信您也可以通过在使用 innerHTML 修改 HTML(例如在您的 label DOM 元素上使用 children)并在那时应用侦听器后再次获取复选框来解决此问题,但我不推荐这种方法。

    function ready(fn) {
      if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading"){
        fn();
      } else {
        document.addEventListener('DOMContentLoaded', fn);
      }
    }
    
    function theFunc(e) {
      console.log('clicked');
    }
    
    ready(() => {
      const makeCheckboxDropdown = (input) => {
        if (input.type !== "select-multiple") {
            console.error("The input must be an `select multiple` type!");
            return;
        }
    
        input.options[0].selected = false;
        
        const header = document.getElementById('header');
        const outer = document.createElement('div');
        const options = input.options;
        for (i = 0; i < options.length; i++) {
          let div = document.createElement('div');
          div.classList.add('checkbox');
    
          let label = document.createElement('label');
    
          let cb = document.createElement('input');
          cb.type = "checkbox";
          cb.value = options[i].value;
          cb.addEventListener('change', theFunc);
    
          label.appendChild(cb);
          
          let value = document.createElement('span');
          value.textContent = options[i].value;
          label.appendChild(value);
    
          div.appendChild(label);
          outer.appendChild(div);
        }
        header.parentNode.insertBefore(outer, header.nextSibiling);
      };
    
      const a = document.getElementById('a');
      makeCheckboxDropdown(a);
    })
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <title>repl.it</title>
        <link href="index.css" rel="stylesheet" type="text/css" />
      </head>
      <body>
        <script src="index.js"></script>
        <div class="content">
            <div class="clearfix"></div>
            <div class="box box-primary">
                <div class="box-body">
                    <h4 id="header">Dias da Semana</h4>
                    <select id="a" multiple>
                        <option>1:00 am</option>
                        <option>2:00 am</option>
                        <option>3:00 am</option>
                        <option>4:00 am</option>
                        <option>5:00 am</option>
                        <option>6:00 am</option>
                        <option>7:00 am</option>
                        <option>8:00 am</option>
                        <option>9:00 am</option>
                        <option>10:00 am</option>
                        <option>11:00 am</option>
                        <option>12:00 pm</option>
                        <option>13:00 pm</option>
                        <option>14:00 pm</option>
                        <option>15:00 pm</option>
                        <option>16:00 pm</option>
                        <option>17:00 pm</option>
                        <option>18:00 pm</option>
                        <option>19:00 pm</option>
                        <option>20:00 pm</option>
                        <option>21:00 pm</option>
                        <option>22:00 pm</option>
                        <option>23:00 pm</option>
                        <option>00:00 am</option>
                    </select>
                </div>
            </div>
        </div>
      </body>
    </html>

    【讨论】:

    • 谢谢!正如您答案中的链接所建议的那样,我通过将label.innerHTML += [...] 更改为label.appendChild(document.createTextNode([...])) 来解决它。
    猜你喜欢
    • 2010-11-27
    • 2011-03-06
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多