console.log("hello...">

Why aren't cloneNode <script> tags executed?

Cloning <script> tags are not executed. What for?

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 welcome scripts in the document, but only one is executed.

http://jsbin.com/zuxoro/1/edit?html,console,output

This is part of the bigger problem I'm working on, so I know this is a stupid thing.

+8
javascript dom
source share
3 answers

This behavior is required by the W3C HTML5 specification .

Each <script> element has a property flag called "already running". The specification states:

Initially, script elements must have this unset flag (script blocks, when created, are not "already running"). The cloning steps for script elements should set the flag “already running” on the copy if it is set to the cloned element.

And then, later:

If the script element is marked as “already running,” then the user agent must abort these steps at this point. script is not executed.

The solution is simply not to clone the elements of the script, but to create completely new elements filled with the same content.

+5
source share

Basically, the browser does the following when it executes <script> on the page:

If the script <script> not been executed before it does the following:

  • Accepts text from <script> ;
  • Call eval(thatScriptText) ;
  • Marks the <script> DOM node as done;

When you clone a node, it also receives an internal "executable" flag, which prevents subsequent script executions.

Solution: if you want to restart the script, follow steps # 1 and # 2. In this case, cloning is not required.

+1
source share

I do not know why this does not work with cloneNode , but you can achieve the same result by copying 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> 
+1
source share

All Articles