我想在另一个页面中通过XMLHttpRequest加载此代码(1)
<input type="text" onkeypress="info(event)"/>
<script>
function info(e) { console.log(e.keyCode); }
</script>
这是(2)我试过的方式......
<div id="x"></div>
<script>
var xhr = new XMLHttpRequest();
xhr.onload = handleResponse.bind(xhr);
xhr.open("POST","test.php",true);
xhr.send();
function handleResponse() {
var x = document.getElementById("x");
x.innerHTML = this.responseText;
var js = x.getElementsByTagName("script")[0];
eval(js.innerText);
}
</script>
...这是我在按键时遇到的错误:
Uncaught ReferenceError: info is not defined
为什么找不到info()
,因为它的定义是eval'd?如果(2)应该不知道(1),如何在按键上触发信息?没有jQuery。
根据迈克的建议,我创建了this question来解决导致解释此问题的分离问题。
答案 0 :(得分:1)
范围。你没有在window
上评估它,你将它添加到该函数handleResponse
的范围内,因此它不会存在于handleResponse之外。此外,在这种情况下,你根本不需要eval。就这样做:
function handleResponse() {
var x = document.getElementById("x");
x.innerHTML = this.responseText;
// grab all script elements, as an array
// (rather than document.queryS..'s NodeList answer)
var js = [].slice.call( x.querySelectorAll("script"), 0);
// add all those scripts to the head element
js.forEach(function(scriptElement) {
document.head.appendChild(scriptElement);
// this moves the script element from [x] to [head]
});
}
浏览器已经知道如何解释脚本,但如果您希望它们执行而不是作为非活动DOM节点插入,则需要向head
添加元素。
最后,如果你真的需要eval
(由于上述原因,你有99.99%的时间不这样做),使用new Function
要好得多,因为这样你就可以捕获语法和运行时错误,而不是做“谁知道什么”:
try {
var evaluator = new Function("return " + js.innerText + ";");
try {
evaluator();
} catch (runtimeError) {
console.log("ERROR: eval'd code is legal, but runtime-broken");
}
} catch (syntaxError) {
console.log("ERROR: js.innerText has syntax errors");
}