Daniel Daniel - 1 year ago 115
HTML Question

Execution of dynamically generated Javascript

I was reading this question with the accepted answer being:

Script added by setting the innerHTML property of an element doesn't get executed.

But when I try to change the innerHTML of the first
tag in the following code:

document.querySelectorAll("script")[0].innerHTML = 'console.log("Test")';

I can see the injected code for the
element being executed (the
function outputs Test).

Furthermore if I remove the first empty
tag (thus making the first element
refer to the script itself), the script is changed in the DOM, but the code is never executed.

document.querySelectorAll("script")[0].innerHTML = 'console.log("Test")';

What prompts this behaviour?

Answer Source

This is described in Scripting. When the script is being prepared,

  1. At step 2, the "parser-inserted" flag is removed:

    If the element has its "parser-inserted" flag set, then set was-parser-inserted to true and unset the element's "parser-inserted" flag.

  2. At step 4, before restoring the "parser-inserted" flag, the steps are aborted

    If the element has no src attribute, and its child nodes, if any, consist only of comment nodes and empty Text nodes, then the user agent must abort these steps at this point. The script is not executed.

Therefore, when you modify it, it will be prepared again:

When a script element that is not marked as being "parser-inserted" experiences one of the events listed in the following list, the user agent must synchronously prepare the script element:

Once the script ran, modifying the contents won't execute them, because script preparation will abort:

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download