Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
663 views
in Technique[技术] by (71.8m points)

javascript - Dynamically adding script element to a div does not execute the script

I am trying to add a script block dynamically to the document. When I do this, the script block is not getting 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 above code does not work. From another post (How do you execute a dynamically loaded JavaScript block?), I saw a reply that if script is added to innerHTML, it will not be executed. Instead of directly using innerHTML, create a div with this innerHTML and use appendChild to add the 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>

How ever, this solution also did not work for me.

In another reply, 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 do this in a function then it does not 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 can see that the function is available after the script is evaled. and is available in the function createFunction. Outside createFunction() scope, hello() is not available.

What am I doing wrong? Am I missing something very basic? Please check and help.

Thanks, Paul

P.S. I don't use jQuery. I am using chrome to test this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Would like to point out that the reason the 3rd snippet you provided works inside the for loop, but not outside is because you are using eval. eval takes a string and executes it as js, which is why it is working inside the loop, but using eval isn't parsing it for future use, which is causing it to be unusable elsewhere. Therefore, when you go to call it outside the loop, you get a reference error.

UPDATE:

If you are getting the string back with the <script> tags in it, you can just parse out 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 don't really see the point of this, but if you really want to do this you can create a new script element and then set it's innerHTML to the function, then append the new script to a div.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...