我有一个JavaScript变量:
var foo='<script type="text/javascript">alert("Hello World");<\/script>'
变量通过element.innerHTML=foo;插入页面后,大约在页面加载后10秒钟触发事件。是否有一种方法可以在插入后立即执行“alert”函数?
我有一个JavaScript变量:
var foo='<script type="text/javascript">alert("Hello World");<\/script>'
eval
或类似的eval
机制。在多年的JavaScript编程中,我从未不得不使用它,我建议您看看是否有其他方法来实现您的实际目标。eval
代码,例如:var script = foo.replace(/^<script[^>]*>/, "").replace(/<\/script>$/, "");
eval(script);
// Or window.evalInGlobalScope(script); // -- See below
window.evalInGlobalScope = (function() {
var fname, scr;
// Get a unique function name
do {
fname = "__eval_in_global_test_" + Math.floor(Math.random() * 100000);
}
while (typeof window[fname] !== 'undefined');
// Create test script
scr = "function " + fname + "() { }";
// Return the first function that works:
return test(evalInGlobalScope_execScript) ||
test(evalInGlobalScope_windowEval) ||
test(evalInGlobalScope_theHardWay) ||
evalInGlobalScope_fail;
function test(f) {
try {
f(scr);
if (typeof window[fname] === 'function') {
return f;
}
}
catch (e) {
return false;
}
finally {
try { delete window[fname]; } catch (e) { window[fname] = undefined; }
}
}
function evalInGlobalScope_execScript(str) {
window.execScript(str);
}
function evalInGlobalScope_windowEval(str) {
window.eval(str);
}
function evalInGlobalScope_theHardWay(str) {
var parent, script, d = document;
parent = d.body || d.documentElement || d.getElementsByTagName('head')[0];
if (parent) {
script = d.createElement('script');
script.appendChild(d.createTextNode(str));
parent.appendChild(script);
}
}
function evalInGlobalScope_fail() {
throw "evalInGlobalScope: Unable to determine how to do global eval in this environment";
}
})();
你不需要做很多改变,只需要一个小小的改动。
现在你有这样一行代码:
oDiv.innerHTML = foo;
只需将其更改为以下三行:
var oScript = document.createElement("script");
oScript.innerHTML = foo;
oDiv.appendChild(oScript);
并且让foo
仅包含原始的JS代码, 而不包括<script>
和</script>
标签。
script
元素上的 innerHTML
不可靠。例如,在所有版本的 IE 中都会失败。因此,在我的答案中使用了各种机制来查找正确的 evalInGlobalScope
函数。 - T.J. CrowderexecScript
。Firefox和其他一些浏览器提供了window.eval
(与eval
不同)。在几乎所有其他情况下,创建一个文本节点(而不是设置innerHTML
)可以解决问题。再次参考我的答案中的evalInGlobalScope
。它测试浏览器支持哪种机制(一次)。我在几年前做了大量研究。 - T.J. Crowder
alert
就会立即发生。)如果你提供更多上下文信息,几乎肯定有更好的方法来实现你想要的效果。 - T.J. CrowderinnerHTML
正在标准化过程中,并且在跨浏览器方面比许多其他东西更好--只是不适用于此(脚本注入)。如果您尝试使用它创建无效的DOM结构(例如将div
的innerHTML
设置为“<tr><td>Hi there</td></tr>”),则可靠性会大大降低,但除了脚本、无效结构以及旧浏览器中某些表单字段的奇怪行为之外,它非常可靠。 - T.J. CrowderinnerHTML
很容易被滥用。实际上,每当我看到xyz.innerHTML += "mumble";
这样的代码时,我都会皱眉。:-) 但是,如果你知道自己在做什么,它在进行整体替换时非常有用。而且,在script
元素上根本不需要任何属性,除非你使用的不是 JavaScript,或者(对于内联script
标记)如果你想要在支持它的浏览器中使用defer
或async
。 - T.J. Crowder