script tag only run the first time after inserted in the DOM
It is very curious why the script tag only runs once after inserted into the dom.
script = document.createElement('script');
script.type = 'text/javascript'
script
//output: <script type="text/javascript"></script>
document.body.appendChild(script);
script.innerHTML = 'console.log("Attempt one")'
//output Attempt one
script.innerHTML = 'console.log("Attempt two")'
script.innerHTML = 'console.log("Attempt three")'
//second and third attempts emit no output
Is there an开发者_高级运维y way to allow the other changes to script text to run?
I've already tried wrap it into a function and no success...I couldn't find any explanation why the log
runs the first time and not the following ones
Just to clarify here, that the code above could be a bad approach, etc. But the question really refers to the behaviour and why does it happens.
After playing around in the past minutes I could notice that the javascript will only run once for each script tag once it is both appended to the DOM and has a content.
So for example, you could have a script
tag appended to the DOM without any content...
that wouldn't fire the javascript. But as soon as you add content to that tag with innerText
, innerHTML
, etc...it will fire the javascript straight away.
It is quite interesting to notice that each script tag, seems to handle a flag which is set to false
every time javascript run for that specific tag, then after this happens it won't fire again, no matter why.
here are some tests that are interesting too:
Normal behaviour
var script = document.createElement('script');
document.body.appendChild(script);
script.innerHTML = 'alert("attemp one")';
// outputs alert
script.innerHTML = 'alert("attemp two")';
// no output
Deep Cloning node
var clone = script.cloneNode(true);
// <script>alert("attemp two")</script>
document.body.replaceChild(clone, script);
// no output
Simple Cloning node
var clone = script.cloneNode();
// <script></script>
clone.innerHTML = 'alert("attemp two")';
document.body.replaceChild(clone, script);
// no output
Replacing for new tag
var newScript = document.createElement('script');
newScript.innerHTML = 'alert("attempt three")';
document.body.replaceChild(newScript, script);
// output alert
So as you can see the script tag will hold the alreadyExecuted
attribute no matter why, if you clone it by generating an exact copy or not...
Which makes me think if is there any way to set this flag to its original initial value instead of creating a new script
tag.
But in the worst case if you really need to use this. It is not difficult to create an action that will get the script
, create a new one with the same attributes if you have some and then replace it with the old but with new content. The javascript would run like the first time.
The following script can easily be called and that will replace the old script tag for a new one and execute the new javascript by simply providing the script tag you wish to replace contents.
function innerScript(element) {
var newElement = document.createElement('script'),
attr;
for (attr = 0; attr < element.attributes.length; attr += 1) {
newElement.setAttribute(element.attributes[attr].name, element.attributes[attr].value);
}
element.parentNode.replaceChild(newElement, element);
return newElement;
}
just the way it is. you shouldn't generally have to add new code to an existing tag; either create a new tag or make better use of functions and events.
Changing the inner text of the <script />
DOM node at arbitrary points in script execution doesn't trigger the entire script to be re-executed, no.
Create a new script tag or, better, refine your approach. You should never find yourself needing to inject script tags; instead, just execute these function calls in the normal manner.
精彩评论