Dynamically adding script element to div does not execute script

I am trying to add a script block dynamically to a document. When I do this, the script block is not executed.

<body> <div id="dynamicDiv"> </div> <script type="text/javascript"> var elem = document.getElementById("dynamicDiv"); var tmpStr = "<script type=\"text\/javascript\"> "; tmpStr += "function hello (val)"; tmpStr += "{"; tmpStr += "alert('hello ' + val);"; tmpStr += "}"; tmpStr += "<\/script>"; elem.innerHTML = tmpStr; hello("World"); </script> </body> 

The code above does not work. From another post ( How do you execute a dynamically loaded JavaScript block? ), I saw the answer that if a script is added to innerHTML, it will not be executed. Instead of using innerHTML directly, create a div with this innerHTML and use appendChild to add a script.

 <body> <div id="dynamicDiv"> </div> <script type="text/javascript"> var elem = document.getElementById("dynamicDiv"); var tmpStr = "<script type=\"text\/javascript\"> "; tmpStr += "function hello (val)"; tmpStr += "{"; tmpStr += "alert('hello ' + val);"; tmpStr += "}"; tmpStr += "<\/script>"; var newdiv = document.createElement('div'); newdiv.innerHTML = tmpStr; elem.appendChild(newdiv); hello("World"); </script> </body> 

Be that as it may, this solution also did not work for me.

In another answer, I again saw that we should get the script elements and execute them using eval.

 <body> <div id="dynamicDiv"> </div> <script type="text/javascript"> var elem = document.getElementById("dynamicDiv"); var tmpStr = "<script type=\"text\/javascript\"> "; tmpStr += "function hello (val)"; tmpStr += "{"; tmpStr += "alert('hello ' + val);"; tmpStr += "}"; tmpStr += "<\/script>"; var newdiv = document.createElement('div'); newdiv.innerHTML = tmpStr; elem.appendChild(newdiv); var scripts = newdiv.getElementsByTagName('script'); for (var ix = 0; ix < scripts.length; ix++) { eval(scripts[ix].text); } hello("World"); </script> </body> 

This solution works for me.

But if you do this in a function, then it won’t work.

 <body> <div id="dynamicDiv"> </div> <script type="text/javascript"> function createFunction(){ var elem = document.getElementById("dynamicDiv"); var tmpStr = "<script type=\"text\/javascript\"> "; tmpStr += "function hello (val)"; tmpStr += "{"; tmpStr += "alert('hello ' + val);"; tmpStr += "}"; tmpStr += "<\/script>"; var newdiv = document.createElement('div'); newdiv.innerHTML = tmpStr; elem.appendChild(newdiv); var scripts = newdiv.getElementsByTagName('script'); for (var ix = 0; ix < scripts.length; ix++) { eval(scripts[ix].text); } hello("World 1"); } createFunction(); hello("World 2"); </script> </body> 

I see that the function is available after the script value is changed. and is available in the createFunction function. Outside the scope of createFunction (), hello () is not available.

What am I doing wrong? Did I miss something? Please check and help.

Thanks Paul

PS I do not use jQuery. I use chrome to check this out.

+4
source share
2 answers

I would like to note that the reason you provided the third snippet works inside the for loop, but not outside because you are using eval . eval takes a string and executes it as js, so it works inside a loop, but using eval does not parse it for future use, which makes it unusable elsewhere. Therefore, when you go to a call outside the loop, you get a reference error.

UPDATE:

If you return a string with <script> tags, you can simply parse the script tags.

 var string = "<script type=\"text\/javascript\"> "; string += "function hello (val)"; string += "{"; string += "alert('hello ' + val);"; string += "}"; string += "<\/script>"; string = string.replace(/<(script|\/script).*?>/g,''); function createFunction() { var elem = document.getElementById("dynamicDiv"); var script = document.createElement('script'); script.innerHTML = string; elem.appendChild(script); hello("World 1"); } createFunction() hello('world 2'); 

JSFiddle: http://jsfiddle.net/3wYD6/

I really don't see the point in this, but if you really want it, you can create a new script element and then set its innerHTML to a function and then add a new script to the div.

 var elem = document.getElementById("dynamicDiv"), script = document.createElement('script'); script.innerHTML = 'function hello (val) {' + 'alert("hello " + val);' + '}'; elem.appendChild(script); hello('world'); 
+2
source

In the first attempt, you create a string, and the js interpreter processes it as a string, not an html tag, so js really does not care about the script tags presented in this string.

Then, of course, it works when you start using eval (), because eval is evil :))

In the end, you can dynamically create script tags and then populate it with code:

 var elem = document.getElementById("dynamicDiv"), scriptTag = document.createElement('script'), scriptTagCode = 'function hello (val){alert("hello " + val);}'; scriptTag.innerHTML = scriptTagCode; elem.appendChild(scriptTag); hello('foo'); 
0
source

All Articles