动态地将脚本元素添加到div不会执行脚本

时间:2013-03-22 09:54:42

标签: javascript

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

<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 dynamically loaded 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()不可用。

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

谢谢, 保罗

P.S。我不使用jQuery。 我正在使用chrome来测试它。

2 个答案:

答案 0 :(得分:2)

想要指出您提供的第3个代码段在for循环内部工作的原因,但不在外部是因为您使用的是evaleval接受一个字符串并将其作为js执行,这就是它在循环内工作的原因,但是使用eval并不解析它以供将来使用,这导致它在其他地方无法使用。因此,当您在循环外调用它时,会出现引用错误。

更新:

如果您收到包含<script>标记的字符串,则可以解析脚本标记。

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/

我真的没有看到这一点,但是如果你真的想要这样做,你可以创建一个新的脚本元素,然后将它的innerHTML设置为该函数,然后将新脚本附加到div。

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

答案 1 :(得分: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');