'Input in a label created via javascript is not checked

My html and Javascript is as below:

const container = document.getElementById('container')

const label = document.createElement('label')
const input = document.createElement('input')

input.type = 'checkbox'
input.checked = true

label.appendChild(input)
label.innerHTML += 'This is a label'

container.appendChild(label)
<html>

<body>
    <div id = 'container'></div>
</body>

</html>

The result is that I just get an unchecked checkbox in the label. However, if I remove the label from the equation and just append the input to the container, then it is pre-checked as expected. How come setting input.checked = true has no effect when the input is in a label?

const container = document.getElementById('container')

const input = document.createElement('input')

input.type = 'checkbox'
input.checked = true

container.appendChild(input)
<html>

<body>
  <div id='container'></div>
</body>

</html>


Solution 1:[1]

The line:

label.innerHTML += 'This is a label'

takes your existing innerHTML and re-writes it, destroying any (non-delegated) event-handlers or existing properties.

If, instead of label.appendChild(), you use:

label.append(input, 'This is a label');

Then it works to add the text as well as the <input> to the <label>:

const container = document.getElementById('container')

const label = document.createElement('label')
const input = document.createElement('input')

input.type = 'checkbox'
input.checked = true

label.append(input, 'This is a label');

container.appendChild(label)
<div id='container'></div>

References:

Solution 2:[2]

In place of using innerHTML, which doesn't work well when adding siblings since it destroys and recreates the parent element, it's better using appendChild and add the sibling as a TextNode:

const container = document.getElementById('container')

const label = document.createElement('label')
const input = document.createElement('input')

input.type = 'checkbox'
input.checked = true

label.appendChild(input)
label.appendChild(document.createTextNode("This is a label")); 

container.appendChild(label)
<html>
<body>
<div id = 'container'></div>
</body>
</html>

This will also prevent script injection whether you'll decide, in the future, to allow users decide the label.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2