4

我正在尝试将脚本块动态添加到文档中。当我这样做时,脚本块没有被执行。

<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>

上面的代码不起作用。在另一篇帖子(How do you execute a dynamic load a JavaScript block?)中,我看到一个回复​​,如果将脚本添加到innerHTML,它将不会被执行。不要直接使用innerHTML,而是使用此innerHTML 创建一个div,然后使用appendChild 添加脚本。

<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>

然而,这个解决方案也对我不起作用。

在另一个回复中,我再次看到我们应该获取脚本元素并使用 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>

这个解决方案对我有用。

但是如果在一个函数中这样做,那么它就不起作用了。

<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>

我可以看到该函数在脚本被评估后可用。并且在函数 createFunction 中可用。在 createFunction() 范围之外,hello() 不可用。

我究竟做错了什么?我错过了一些非常基本的东西吗?请检查并帮助。

谢谢,保罗

PS我不使用jQuery。我正在使用 chrome 进行测试。

4

2 回答 2

2

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');
于 2013-03-22T10:42:47.280 回答
0

在您的第一次尝试中,您正在创建一个字符串,js 解释器将其作为字符串处理,而不是 html 标记,因此 js 并不真正关心该字符串中显示的脚本标记。

那么当你开始使用 eval() 时它当然会起作用,因为 eval - 是邪恶的:))

毕竟,您可以动态创建脚本标签,然后用代码填充它:

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

scriptTag.innerHTML = scriptTagCode;
elem.appendChild(scriptTag);
hello('foo');
于 2013-03-22T10:20:38.917 回答