Javascript not executing when loaded via XMLHttpRequest but does when loaded with jQuery.load - Stack Overflow

While converting a script to not require jQuery, I've discovered that if I load my content (a part

While converting a script to not require jQuery, I've discovered that if I load my content (a partial html page with html and javascript) via XMLHttpRequest, the javascript in the partial page does not work. But if I load the partial using jQuery.load, it does work.

I've tried digging through jQuery's load function to see if it's doing anything special and nothing jumped out at me. I've been banging my head against the wall and searching for an answer for a couple of days now to no avail.

What am I doing wrong/how can I make it work like it does when loaded with jQuery.load?

EDIT

I got the XMLHttpRequest method to work by splitting out out my javascript from the html in the fragment and loading the javascript using the suggested technique here: . However, that still does not provide an explanation of why jQuery.load works. Is jQuery umtimately parsing the HTML and doing the same thing for any scripts it finds within the content it loads?

I've set up a plunker () with the following code that demonstrates the issue. Note: once you load the fragment with jQuery, it will continue to work and you'll have to restart the plunk for the XMLHttpRequest method to fail again.

index.html:

<!DOCTYPE html>
<html>

  <head>
    <script data-require="jquery@*" data-semver="3.0.0" src=".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>

While converting a script to not require jQuery, I've discovered that if I load my content (a partial html page with html and javascript) via XMLHttpRequest, the javascript in the partial page does not work. But if I load the partial using jQuery.load, it does work.

I've tried digging through jQuery's load function to see if it's doing anything special and nothing jumped out at me. I've been banging my head against the wall and searching for an answer for a couple of days now to no avail.

What am I doing wrong/how can I make it work like it does when loaded with jQuery.load?

EDIT

I got the XMLHttpRequest method to work by splitting out out my javascript from the html in the fragment and loading the javascript using the suggested technique here: https://stackoverflow./a/11695198/362958. However, that still does not provide an explanation of why jQuery.load works. Is jQuery umtimately parsing the HTML and doing the same thing for any scripts it finds within the content it loads?

I've set up a plunker (https://plnkr.co/edit/wE9RuULx251C5ARnUbCh) with the following code that demonstrates the issue. Note: once you load the fragment with jQuery, it will continue to work and you'll have to restart the plunk for the XMLHttpRequest method to fail again.

index.html:

<!DOCTYPE html>
<html>

  <head>
    <script data-require="jquery@*" data-semver="3.0.0" src="https://cdnjs.cloudflare./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>
Share Improve this question edited May 23, 2017 at 12:08 CommunityBot 11 silver badge asked Dec 12, 2016 at 22:00 JohnJohn 2454 silver badges10 bronze badges 10
  • updateDiv function is not defined at html at global attribute event when document is loaded. – guest271314 Commented Dec 12, 2016 at 22:08
  • 1 @Barmar OP's Question is slightly more plicated than linked Question and Answers. That is, separating html elements within fragmentToLoad.html that are not <script> from <script> element within fragmentToLoad.html; also, OP needs to attach click event listener to each a element, which linked Question does not address. From perspective here, the linked Question is not an "exact duplicate". – guest271314 Commented Dec 12, 2016 at 22:45
  • 1 jQuery parses the HTML and searches for <script> tags, and emulates them itself because assigning to .innerHTML doesn't execute scripts. – Barmar Commented Dec 12, 2016 at 22:50
  • OP is attempting to not use jQuery. How does linked Question address attaching click event to dynamic <a> elements appended to document? – guest271314 Commented Dec 12, 2016 at 22:50
  • 3 The reason nothing in the .load() function jumped out at you is that it's done in the .html() function. .load() is simply a shortcut that performs an AJAX call and then uses .html() on the result. Finding the actual code that performs the <script> emulation can be difficult, because it's buried way down. – Barmar Commented Dec 12, 2016 at 23:00
 |  Show 5 more ments

1 Answer 1

Reset to default 3

You can use single .html file, and you are on the correct track by splitting the html content - though you can also split the html content of a single file, rather than requesting two files. @Barmar explains the functionality of jQuery's .load() method at this ment.

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745336966a4623149.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信