Javascript在通过XMLHttpRequest加载时不执行,但在使用jQuery.load加载时执行

时间:2016-12-12 22:00:29

标签: javascript jquery html ajax xmlhttprequest

在将脚本转换为不需要jQuery时,我发现如果我通过XMLHttpRequest加载我的内容(带有html和javascript的部分html页面),则部分页面中的javascript不起作用。但是如果我使用jQuery.load加载部分,它确实有效。

我已经尝试过挖掘jQuery的加载函数,看看它是否做了什么特别的事情,没有任何东西跳出来。我一直在撞墙,几天都找不到答案。

我做错了什么/如何让它像加载jQuery.load时那样工作?

修改

我通过从片段中的html中分离出我的javascript并使用建议的技术加载javascript来获得XMLHttpRequest方法:https://stackoverflow.com/a/11695198/362958。但是,这仍然没有解释为什么jQuery.load工作。 jQuery是否非常仔细地解析HTML并对其在加载的内容中找到的任何脚本执行相同的操作?

我已经使用以下代码设置了一个plunker(https://plnkr.co/edit/wE9RuULx251C5ARnUbCh)来演示该问题。注意:一旦用jQuery加载片段,它将继续工作,你将不得不重新启动plunk,以使XMLHttpRequest方法再次失败。

的index.html:

<!DOCTYPE html>
<html>

  <head>
    <script data-require="jquery@*" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>

  <h3>Buttons</h3>  
    <div>
      <input type="button" value="Load with XMLHttpRequest" onclick="loadXMLDoc('ajaxContentDiv', 'fragmentToLoad.html');">  (Links do not work if loaded this way... Script from fragmentToLoad.html not loaded in DOM?) <br/><br/>
      <input type="button" value="Load with JQuery" onclick="jQuery('#ajaxContentDiv').load('fragmentToLoad.html');">  (Links will work if loaded this way)
    </div>
<br/>
<br/>
<br/>
<div id="ajaxContentDiv">Content will load here...</div>

  </body>

</html>

的script.js:

function loadXMLDoc(targetDivName, url) {

  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open("GET", url, true);
  xmlhttp.onreadystatechange = function () {
      if (xmlhttp.readyState == XMLHttpRequest.DONE) {
          if (xmlhttp.status == 200) {
              document.getElementById(targetDivName).innerHTML = xmlhttp.responseText;
          }
      }
  };
  xmlhttp.send();
}

fragmentToLoad.html:

<div id="divToBeUpdated">
  <span id="stringBox">String here</span>
</div>
<br/>
<h3>Links</h3>
<div>
  <a href="#" onclick="updateDiv('Hello World 1');">Link 1</a><br>
  <a href="#" onclick="updateDiv('Hello World 2');">Link 2</a><br>
  <a href="#" onclick="updateDiv('Hello World 3');">Link 3</a><br>
</div>

<script>
  function updateDiv(string){
    var stringBox = document.getElementById('stringBox');
    stringBox.innerHTML = string;
  }
</script>

1 个答案:

答案 0 :(得分:1)

您可以使用单个.html文件,并通过拆分html内容来处于正确的轨道上 - 尽管您也可以拆分单个文件的html内容,而不是请求两个文件。 @Barmar在此comment解释了jQuery的.load()方法的功能。

的script.js

function loadXMLDoc(targetDivName, url) {

  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open("GET", url, true);
  xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == XMLHttpRequest.DONE) {
      if (xmlhttp.status == 200) {
        // create a `div` elemenent, append response to `div` element
        // get specific elements by `id`, append `script` element to `document.body`
        var content = document.createElement("div");
        content.innerHTML = xmlhttp.responseText
        var div = content.querySelector("#htmlContent");
        var contentScript = content.querySelector("#contentScript");
        var script = document.createElement("script");
        script.textContent = contentScript.textContent;
        document.getElementById(targetDivName).innerHTML = div.innerHTML;
        document.body.appendChild(script);
      }
    }
  };
  xmlhttp.send();
}

fragmentToLoad.html

<div id="htmlContent">
  <div id="divToBeUpdated">
    <span id="stringBox">String here</span>
  </div>
  <br/>
  <h3>Links</h3>
  <div class="links">
    <a href="#">Link 1</a>
    <br>
    <a href="#">Link 2</a>
    <br>
    <a href="#">Link 3</a>
    <br>
  </div>
</div>
<script type="text/javascript" id="contentScript">
  function updateDiv(string) {
    var stringBox = document.getElementById('stringBox');
    stringBox.innerHTML = string;
  }
  // attach `click` event to `.link a` elements here
  var links = document.querySelectorAll(".links a");
  for (var i = 0; i < links.length; i++) {
    (function(link, i) {
      console.log(i)
      link.addEventListener("click", function(e) {
        e.preventDefault();
        updateDiv("Hello World " + i)
      })
    })(links[i], i)
  }
</script>

plnkr https://plnkr.co/edit/7fLtGRSV7WlH2enLbwSW?p=preview