我正在尝试构建一些网站管理员可以嵌入其网站的小工具。
网站站长是否可以通过包含这样的脚本来加载此工具?
<script src="http://mysite/widget.js"></script>
我尝试通过在AJAX中加载它然后在主体上执行appendChild()
来注入它,它正在以这种方式工作但是JS没有被执行。
要注入的内容:
<div>one div</div>
<script>alert('some 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。
答案 0 :(得分:4)
由于您不知道脚本将添加到头部或正文标记的位置 - 因此在执行时,您需要确保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);
但是,添加<script>
标记以在模板中执行某些脚本是没有意义的,因为当您添加DOM时脚本已经在运行,因此请在那里进行所有必要的设置。
答案 1 :(得分:2)
请参阅Maximus的回答。
是的,出于安全考虑,默认的本机innerHTML不会执行js。
jQuery或zepto $ .fn.append()可以满足您的需求,这就是原因(来自zepto源代码)
if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
(!el.type || el.type === 'text/javascript') && !el.src)
window['eval'].call(window, el.innerHTML)
你可以在$ .fn.append函数中看到它是否是一个脚本,如果是,它将使用eval
来运行内容。您可能需要eval
,但要小心,因为一些网站管理员可能会提供“恶意代码”