I dynamically create a checkbox that has an EventListener. Unfortunately the EventListener doesn't work if I change the text of the checkbox-label with innerHTML
:
let label = document.createElement('label'),
input = document.createElement('input');
input.setAttribute('type', 'checkbox');
input.addEventListener('change', () => alert('Change Detected'));
label.appendChild(input);
document.body.appendChild(label);
label.innerHTML += 'Select Me!';
How can I circumvent this problem and why does it even exist?
Here a working snippet without the innerHTML
:
let label = document.createElement('label'),
input = document.createElement('input');
input.setAttribute('type', 'checkbox');
input.addEventListener('change', () => alert('Change Detected'));
label.appendChild(input);
document.body.appendChild(label);
When you concatenate to the innerHTML
of an element, its contents are cleared, the existing HTML string is concatenated with the new string, and then the container's contents are re-calculated according to the new HTML string. ~~Listeners~~ Elements attached to elements previously in the container do not survive the serialization process - the children of the container after changing innerHTML
are new.
Append a text node instead:
let label = document.createElement('label');
let input = document.createElement('input');
input.setAttribute('type', 'checkbox');
input.addEventListener('change', () => alert('Change Detected'));
label.appendChild(input);
document.body.appendChild(label);
label.appendChild(document.createTextNode('Select Me!'));
Or use insertAdjacentHTML
:
let label = document.createElement('label');
let input = document.createElement('input');
input.setAttribute('type', 'checkbox');
input.addEventListener('change', () => alert('Change Detected'));
label.appendChild(input);
document.body.appendChild(label);
label.insertAdjacentHTML('beforeend', 'Select Me!');