2017-12-13 5 views
1

select multiple 입력을 사용하고이 선택 항목의 옵션에 따라 확인란을 생성하는 함수를 만들었습니다. 그런 다음 각 체크 박스가 클릭 할 때 어떤 동작을 실행하기를 원합니다. 이 기능은 다음과 같습니다프로그래밍 방식으로 생성 된 addEventListener가 작동하지 않습니다.

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

모든 작동 : 의도 한대로 체크 박스가 생성됩니다. 체크 상자를 클릭하면 아무 것도 나타나지 않습니다. 그것은 콘솔에서 "clicked"를 기록해야하지만 아무 일도 일어나지 않습니다. 이상하게도 브라우저 디버그 콘솔을 통해 동일한 EventListener를 추가하면 작동합니다.

여기 무슨 일입니까?

편집 :repl.it 예.

답변

2

이미 확인란을 추가 한 후 레이블에 innerHTML을 사용하는 경우 문제가 발생합니다. 작동하는 한 가지 대안은 아래와 같이 약간 수정 된 것입니다. 내가 한 것은 값과 함께 다른 요소 (span, document.createTextNode을 사용할 수도 있음)를 추가하는 것입니다. 이 작업은 그 안에 체크 박스가있는 요소에 innerHTML을 사용하고 있지 않기 때문에 안전합니다.

innerHTML이 수행하는 작업에 대한 설명은이 질문에서 볼 수 있습니다. here.

난 당신이 또한 당신이 (당신의 label DOM 요소에 children를 사용하여 예를 들어) innerHTML으로 HTML을 수정 한 후 다시 체크 박스를 얻고 그 시점에서 리스너를 적용하여이 문제를 해결할 수 있으리라 생각합니다,하지만 난 것이 좋습니다 않을 것이다 방법.

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>

+0

감사합니다! 답안의 링크에서 알 수 있듯이'label.appendChild (document.createTextNode ([...]))'에'label.innerHTML + = [...]'을 변경하여 해결했습니다. –

관련 문제