以编程方式创建的复选框上的addEventListener不起作用

时间:2017-12-13 17:57:20

标签: javascript events checkbox addeventlistener

我已经创建了一个函数,它接受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示例。

1 个答案:

答案 0 :(得分:2)

在您添加了复选框后,在标签上使用innerHTML时出现此问题。一种可行的替代方案是稍作修改,如下所示。我所做的是追加另一个元素(一个范围,你也可以使用document.createTextNode)和值。此操作是安全的,因为我没有在其中包含复选框的元素上使用innerHTML

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

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

&#13;
&#13;
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);
})
&#13;
<!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>
&#13;
&#13;
&#13;