这是一个与AJAX相关的非常普遍的问题,但是我似乎找不到适合我的情况的问题,因为其中大多数都使用jQuery和其他原因。可能我的效率不高/不建议使用,但是无论哪种方式,我们都可以。
我有一个按钮[为了方便起见,我们将其称为btn
。
它监听点击事件。当用户单击按钮时,它会向与主要HTML / CSS / JS文件位于同一目录中的.txt文件发出AJAX请求。我们称之为test.txt
。
现在,它更改了<html>
的innerHTML(而不是头部/主体,html),而innerHTML是AJAX请求的响应。
test.txt
保存HTML代码。在该HTML代码中有<script src="another-js-file.js">
。
这不会执行,这就是问题所在。
在对我尖叫之前, INNERHTML不会执行任何脚本,我知道。我看到其他答案说要在另一个div内的div中创建一个<script>
标记,但它似乎不适用于外部js文件,解决方案的确使用了innerHTML。
好的,这是草图:
btn.onclick = function(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState = XMLHttpRequest.DONE){
document.documentElement.innerHTML = this.responseText;
}
}
xhr.open("GET", "./test.txt");
xhr.send();
}
test.txt
所在的位置:
<head>
<title>Document</title>
<link rel="stylesheet" href="test.css">
<script src="another-js-file.js"></script>
</head>
<body>
<h1>Hello World!</h1>
</body>
没有jQuery。
答案 0 :(得分:0)
我发现通过创建一个脚本元素并将其源设置为“ another-file.js”,就像这样:
var script = document.createElement("script");
script.src = "test.js";
document.body.appendChild(script);
THIS GOES AFTER document.documentElement.innerHTML = this.responseText;
答案 1 :(得分:0)
在您最初写的XHR请求中,我注意到了
if(xhr.readyState = XMLHttpRequest.DONE)
这实际上应该是三重===而不是一个。
将此功能添加到发出XHR请求的初始JS文件中,
function setInnerHtml(el, html) {
el.innerHTML = html;
// Get all the scripts from the new HTML
const scripts = el.querySelectorAll('script');
// Loop through all the scripts
for (let i = 0; i < scripts.length; i++)
{
// Create a new script
const s = document.createElement('script');
// Go through all the attributes on the script
for (let j = 0; j < scripts[i].attributes.length; j++) {
const a = scripts[i].attributes[j];
// Add each attribute to the new script
s.setAttribute(a.name, a.value);
}
// Incase there is code inside the script tag
// Example: <script>alert</script>
s.innerHTML = scripts[i].innerHTML;
// Append the new script to the head (you could change this to the end of the body as well)
document.head.appendChild(s);
}
}
然后,当您设置根文档对象的innerHTML时,请改用上述功能。
if(xhr.readyState === XMLHttpRequest.DONE){
setInnerHtml(document.documentElement, this.responseText);
}