将脚本附加到HTML后运行脚本

3

我有一个包含HTML标签的字符串:

var str = '<div><p>Examplee</p></div><script>alert("testing!")</script>';

然后,我将它附加到HTML中:
document.body.innerHTML += str;

当内容被追加但脚本不执行时,有没有办法强制执行它?


因为脚本在被附加时不会运行,所以需要在页面加载或操作事件上运行,您需要为其添加触发器。 - clearshot66
我该如何添加触发器?我试图将警报包装在一个函数中,在附加后调用它,但仍然无法正常工作。 - nick
尝试这个:https://stackoverflow.com/questions/7017241/append-and-call-dynamic-javascript-function-with-jquery - clearshot66
1
@clearshot66:OP似乎没有使用jQuery,也没有标记[标签:jQuery]。 - T.J. Crowder
@T.J.Crowder OP也从未说过他们不能,这就是为什么我没有将其作为答案的原因。 - clearshot66
3个回答

8
首先,要说明的是:当然,只有在信任脚本的情况下才能这样做。 :-)
有几种方法可以实现这个目标。基本上,您需要:
1. 获取脚本的文本内容 2. 运行它
获取文本的一种方法是直接添加脚本,然后找到它并获取其文本内容:
document.body.innerHTML += str;
var scripts = document.querySelectorAll("script");
var text = scripts[scripts.length - 1].textContent;

在已过时的浏览器上,您可能需要进行特性检测,以判断textContentinnerText哪个可用。
您可能希望给它一个标识符(idclass等),这样您就不必像那样通过位置来查找它了。
或者,您可以像PrototypeJS库一样尝试使用正则表达式从字符串中获取它。您可以在这里找到他们执行此操作的源代码(查找extractScripts)。

运行脚本

一旦您获得了脚本的文本,您有几个选项:
  • Use indirect eval (aka "global eval") on it: (0, eval)(text). This is not the same as eval(text); it runs the code in global scope, not local scope.

  • Create a new script element, set its text to the text, and add it

    var newScript = document.createElement("script");
    newScript.textContent = text;
    document.body.appendChild(newScript);
    

    If doing that, might make sense to remove the original, though it doesn't really matter.

示例,添加script元素并获取文本后使用间接eval

var str = '<div><p>Examplee</p></div><script>alert("testing!")<\/script>';
document.body.innerHTML += str;
var scripts = document.querySelectorAll("script");
(0, eval)(scripts[scripts.length - 1].textContent);

假设您并不真正使用+=document.body.innerHTML上,因为它会构建整个页面的HTML字符串,然后追加到它上面,最后将整个页面拆除,然后解析新的HTML以构建一个新的页面。我认为这只是您问题中的一个示例。

1
jQuery提供了$.getScript(url [,success])函数。您可以从单独的jquery文件中加载和执行代码,这有助于管理和控制执行流程。
基本上将您的alert("testing!")脚本放在一个单独的文件中,例如同一目录下的alert.js文件。
然后,当向HTML添加员工时,您可以运行该脚本。
var str = '<div><p>Examplee</p></div>';
var url = 'alert.js';    
document.body.innerHTML += str;    
$.getScript(url);

我知道这可能会增加一些工作量,但最好的做法是将JavaScript代码保持独立,不要放在HTML文件中。你也可以使用回调函数来收集用户数据,以便在警告后通知其他进程用户已经被警告。

$.getScript(url, function(){
  //do something after the alert is executed.
});

例如,也许更好的设计是在执行警报后再添加员工。
var str = '<div><p>Examplee</p></div>';
var url = 'alert.js'; 
$.getScript(url, function(){
  document.body.innerHTML += str;
});
编辑:我知道jQuery没有被标记,但我也不是在请求成为这个问题的被接受的答案。我只是提供了另一种选择,对于那些可能遇到相同问题并且使用jQuery的人来说,如果是这种情况,$.getScript是一个非常有用的工具,专门为解决这个问题而设计的。

-1

在页面加载后,您应该更改HTML。尝试这样做:

document.addEventListener("DOMContentLoaded", function(event) {
    document.body.innerHTML += str;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接