Cloned <script> tags do not execute. Why?
Example:
<script id="hello">
console.log("hello execution count ", window.helloCount++);
</script>
<script id="action">
document.body.appendChild(
document.getElementById('hello').cloneNode(true));
console.log('cloned the script');
</script>
After execution, there are two hello scripts in the document, but only one has executed.
http://jsbin.com/zuxoro/1/edit?html,console,output
This is part of a larger problem I am working on, so I know it is a dumb thing to do.
This behavior is required by the W3C HTML5 specification.
Each <script>
element has a property flag called "already started". The specification says:
Initially, script elements must have this flag unset (script blocks, when created, are not "already started"). The cloning steps for script elements must set the "already started" flag on the copy if it is set on the element being cloned.
And then, later:
If the script element is marked as having "already started", then the user agent must abort these steps at this point. The script is not executed.
The solution is simply not to clone script elements, but to create completely new elements that are populated with the same content.
I don't know why it doesn't work with cloneNode
, but you can achieve the same result by copying the innerHTML
to a new script node.
var clone = document.createElement('script');
clone.innerHTML = document.getElementById('hello').innerHTML;
document.body.appendChild(clone);
console.log('copied the script');
<script>
window.helloCount = 1;
</script>
<script id="hello">
console.log("hello execution count ", window.helloCount++);
</script>
<div>Copied scripts do execute</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With