简体   繁体   English

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

[英]addEventListener on programatically created checkbox not working

I've made a function that takes a select multiple input and generate checkboxes based on the options of this select. 我制作了一个函数,该函数接受一个select multiple输入并根据此选择的选项生成复选框。 Then, I want that each checkbox execute some action when clicked. 然后,我希望每个复选框在单击时执行一些操作。 The function is: 该函数是:

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)
}

Everything works: the checkbox are generated as intended. 一切正常:该复选框已按预期生成。 Except that, when I click the checkboxes, nothing happens. 除此之外,当我单击复选框时,没有任何反应。 It should log "clicked" on console, but nothing happens. 它应该在控制台上记录“单击”,但是什么也没有发生。 Strangely, if I add this same EventListener through browser debug console, it works. 奇怪的是,如果我通过浏览器调试控制台添加了相同的EventListener,那么它将起作用。

What is happening here? 这是怎么回事

Edit: an repl.it example. 编辑:一个repl.it示例。

This is an issue with you using innerHTML on the label after you have already appended the checkbox. 这是您附加了复选框后在标签上使用innerHTML的问题。 One alternative that works is a slight modification as below. 一种可行的替代方法是进行如下稍微修改。 What I've done is append another element (a span, you might also use document.createTextNode ) with the value. 我所做的是将另一个元素(一个跨度,您可能还使用document.createTextNode )添加了值。 This action is safe since I am not using innerHTML on the element that has the checkbox inside of it. 此操作是安全的,因为我没有在其中具有复选框的元素上使用innerHTML

An explanation of what innerHTML is doing can be seen in this question here . 什么样的解释innerHTML做可以在这个问题上可以看出这里

I believe you could also fix this by getting the checkbox again after you have modified the HTML with innerHTML (for example using children on your label DOM element) and applying the listener at that point, but I wouldn't recommend that method. 我相信您还可以通过以下方式解决此问题:使用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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM