Javascript 注入外部HTML&;将JS转换为一个页面

Javascript 注入外部HTML&;将JS转换为一个页面,javascript,html,Javascript,Html,我正在尝试构建一些小部件工具,网站管理员可以将它们嵌入到他们的网站中 有没有什么方法可以让网站管理员通过包含这样的脚本来加载这个工具 <script src="http://mysite/widget.js"></script> widget.js function load(content) { var $body = document.body, $div = document.createElement("div"); $div.id = "w

我正在尝试构建一些小部件工具,网站管理员可以将它们嵌入到他们的网站中

有没有什么方法可以让网站管理员通过包含这样的脚本来加载这个工具

<script src="http://mysite/widget.js"></script>
widget.js

function load(content) {
  var $body = document.body,
      $div = document.createElement("div");
  $div.id = "widget";
  $div.innerHTML = content; 
  $body.appendChild($div);
}
内容变量包含HTML和JS,但注入时不会执行JS。

UPDATE 请看马克西姆斯的回答


没错,出于安全考虑,默认的本机innerHTML不会执行js

jQuery或zepto$.fn.append()可以满足您的需要,原因如下(来自zepto源代码)


您可以在函数$.fn.append中看到它是否是脚本,如果是脚本,它将使用
eval
运行内容。您可能需要
eval
到,但要小心,因为有些网站管理员可能会传递“副”代码因为您不知道脚本将添加到何处-到head或body标记中-因此在执行脚本时,您需要确保DOM已准备就绪,因此:

 function load(content) {

    if (document.readyState === "complete" || document.readyState === "loaded") {
         // manipulate DOM
    } else {
       document.addEventListener('DOMContentLoaded', function() {
        // manipulate DOM
    })
}
此外,由于使用
innerHTML
添加的脚本元素无法执行,因此您必须使用
eval
或更好地创建这样的脚本:

var s = document.createElement('script');
s.text = "alert(\"hi\");"
document.getElementsByTagName('head')[0].appendChild(s);

但是,没有必要添加
标记来执行模板中的某些脚本,由于在添加DOM时脚本已经在运行,所以请在那里进行所有必要的设置。

您可以发布包含以下内容的
html代码部分吗js@Armen我在这里编辑了很多好的解决方案:OP在哪里使用
appendChild
来执行脚本?我想OP想要得到
alert('somejs'))
由appendChildok执行,抱歉,没有看到。实际上,它不是
appendChild
不执行脚本,而是
添加了
innerHTML
不执行
appendChild
可以完成。看看我的答案。@Maximus,投赞成票你是对的,谢谢你指出我的错误,本机appendChild函数或window.eval都可以。看起来不错,但我显示的脚本只是一个示例,实际上它比alert()复杂得多。我要加载的js取决于我加载的模板小部件。这就是为什么我把它全部放在由php文件生成的一个文件中。你的意思是我必须分别加载脚本和html?我的意思是你的
widget.js
应该分为
js
html
部分(模板)。使用
widget.js中的代码初始化小部件的js部分,而不是使用模板标记中的代码,因为将它放在那里没有意义。如果您仍然希望将代码放在
标记中,请检查哪个显示递归函数,该函数使用
createElement('script')
替换所有出现的
标记。要使用
eval
只需将
js
作为字符串传递
eval('alert(“hello”)
。但是,
eval()
不是一个好选项,因为它不会在严格的条件下执行。另外,由于
eval
无法可靠地与
html
一起工作,因此您仍然必须使用单独的
js
html
代码,因此我必须向服务器发出两个请求?为html模板打开,为js脚本打开?不,只需将
js
放入
widget.js
,并将模板存储在
js
中的变量中。你可以开始做这件事,然后问另一个有细节的问题,并把它链接到这里
 function load(content) {

    if (document.readyState === "complete" || document.readyState === "loaded") {
         // manipulate DOM
    } else {
       document.addEventListener('DOMContentLoaded', function() {
        // manipulate DOM
    })
}
var s = document.createElement('script');
s.text = "alert(\"hi\");"
document.getElementsByTagName('head')[0].appendChild(s);