Running javascript code called by AJAX

2019-07-08 09:12发布

My site uses pushState to load pages. I have one issue, I want to use javascript on one of the pages but can't because it loads everything with AJAX. So what do I do? I've been told something about "parseScript" but I can't find enough information on it.

--Example--

I load using AJAX On my page I have this script:

<script type="text/javascript">
        function go(){
            alert('1');
        }
    </script>
<a href="javascript:void();" onClick="go();">GO!!!</a>

Nothing happens.

--Edit--

If I open up Google Chrome's debugger: "Uncaught ReferenceError: go is not defined" And the <script> tag is no where to be found

3条回答
可以哭但决不认输i
2楼-- · 2019-07-08 09:41

Browsers don't seem to parse <script> element content that's added to the document via targetElement.innerHTML. That's probably what you're running into.

The best solution is to use a well-tested framework like jQuery for solving problems like this. They've already figured out how to safely and correctly inject scripts into the DOM. There's no sense re-inventing the wheel unless you absolutely can't spare the bandwidth for the library.


One way you might fix this is by separating the JavaScript from the HTML in the Ajax response, either by issuing two requests (probably slower) or by structuring your JavaScript and HTML within a JSON object (probably harder to maintain).

Here's an example:

<script>

function load_content(){
  var req = new XMLHttpRequest();
  req.open("GET", "ajax.json", true);
  req.onreadystatechange = function (e){
    if (req.readyState === 4){
      if (req.status === 200){

        // these three lines inject your JavaScript and
        // HTML content into the DOM
        var json = JSON.parse(req.responseText);
        document.getElementById("target").innerHTML = json.html;
        eval(json.js);
      } else {
        console.log("Error", req.statusText);
      }
    }
  };
  req.send(null);
}

</script>

<a href="#" onclick="load_content()">Load more stuff</a>
<div id="target"></div>

The document ajax.json on the server looks like this:

{
  "js": "window.bar = function (){ console.log(\"bar\"); return false; }",
  "html": "<p><a href=\"#\" onclick=\"bar();\">Log a message</a></p>"
}

If you choose this route, you must either:

  • namespace your functions: MyApp.foo = function (){ ... };, or
  • explicitly add your functions to the global namespace: window.foo = function (){ ... };.

This is because eval executes in the current scope, so your function definitions inherit that scope and won't be globally available. In my example, I chose the latter option since it's just a trivial example, but you should be aware of why this is necessary.

Please make sure to read When is JavaScript's eval() not evil? if you decide to implement this yourself.

查看更多
狗以群分
3楼-- · 2019-07-08 09:51

If I were to do this I would use jquery's load call. That takes care of putting an ajax call ,and parsing tags for script/no-script elements.

IF you dont wanna use jquery, I would suggest you go online and find what the jquery load method does and implement the same as an event handler for your ajax call.

查看更多
放荡不羁爱自由
4楼-- · 2019-07-08 09:56

I think it would be helpful to have a little more detail as to how the Ajax call is made and the content is loaded. That said, a few things of note:

  • the syntax for javascript:void() is invalid. It should be javascript:void(0). For that matter, using javascript:void() on the href of an anchor tag is generally bad practice. Some browsers do not support it. If you must use an tag, set the href to # and add "return false;" to the click event.
  • you should use a button tag instead of the a tag in this case anyway.
  • given what you have provided, it should work (aside from the syntax error with void())
查看更多
登录 后发表回答