执行源于AJAX

时间:2018-10-17 18:19:11

标签: javascript html ajax xmlhttprequest

这是一个与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。

2 个答案:

答案 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);
}