How to load third-party javascript tag asynchronously which has [removed]

前端 未结 7 1043
星月不相逢
星月不相逢 2021-01-04 07:16

We give out a piece of javascript tags such as which site owners put on their site like http://exa

相关标签:
7条回答
  • 2021-01-04 07:24

    Document.write will not work from async script because document is already loaded when script starts working.

    But you can do this:

    document.body.innerHTML = document.body.innerHTML + '<h1>Some HTML</h1>';

    0 讨论(0)
  • 2021-01-04 07:26

    Yes, document.write can't be called from an asynchronously loaded script, because it's detached from the document, so it can't write to it.

    You can see the approach used here for the google maps api to get around this problem. So, it is possible some of your 3rd party scripts that you haven't named, could have the similar callback pattern implemented.

    https://developers.google.com/maps/documentation/javascript/examples/map-simple?hl=EN

    <!DOCTYPE html>
    <html>
      <head>
        <title>Simple Map</title>
        <meta name="viewport" content="initial-scale=1.0">
        <meta charset="utf-8">
        <style>
          html, body {
            height: 100%;
            margin: 0;
            padding: 0;
          }
          #map {
            height: 100%;
          }
        </style>
      </head>
      <body>
        <div id="map"></div>
        <script>
    
    var map;
    function initMap() {
      map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: -34.397, lng: 150.644},
        zoom: 8
      });
    }
    
        </script>
        <script src="https://maps.googleapis.com/maps/api/js?callback=initMap"
            async defer></script>
      </body>
    </html>
    
    0 讨论(0)
  • 2021-01-04 07:27

    How about instead of loading the script by appending a script element, you load the contents of the script URL with an AJAX call and then use eval() to run it in the global scope? Here's an example and I did test it to verify that it works:

    <!DOCTYPE html>
    <html>
    <head>
    <script>
    
    var xmlhttp;
    
    if (window.XMLHttpRequest) {
      xmlhttp = new XMLHttpRequest();
    }else{
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        window.eval(xmlhttp.responseText); //Indirect call to eval to execute in global scope (http://perfectionkills.com/global-eval-what-are-the-options/)
      }
    }
    
    xmlhttp.open("GET", "https://third-party.com/test.js", false); //This is synchronous so that any document.write calls don't overwrite the entire page when they get called after the document is finished rendering. For all intents and purposes, this just loads the script like any other script, synchronously.
    
    xmlhttp.send();
    
    </script>
    </head>
    <body>
    
    <div><h2>Hello World</h2></div>
    
    </body>
    </html>
    

    And here are the contents I had in the test.js file:

    document.write("This is a test...");
    alert("...This is a test alert...");
    console.log("...And a console message.");
    

    I made the AJAX request for the script synchronous so that it would be loaded exactly as if it were a regular embedded script tag. If you run it asynchronously, and the script uses document.write after the page has been fully rendered, it clears the DOM and then writes to it... Kind of annoying actually. Lemme know if this works for you. :)

    0 讨论(0)
  • 2021-01-04 07:29

    What is the 3rd party javascript file?

    If it's Google Maps JavaScript API v3 then make sure you include "&callback=your_init_funct" in the script URL. Then it will call 'your_init_funct' once the maps library is loaded so that you can begin displaying the map.

    Another solution would be bezen.domwrite.js which is available here: http://bezen.org/javascript/index.html

    Demo: http://bezen.org/javascript/test/test-domwrite.html

    0 讨论(0)
  • 2021-01-04 07:40

    The problem with loading a script on a already loaded document (instead of having the browser ignore the document.write()) is that you would delete all existent HTML. See this example so you can understand exactly what's happening, or for more details look at a documentation page for the document.write() method.

    While I know this might not be what you're expecting to get as an answer, I believe you are out of luck since rewriting the script is not an option.

    This appears to be a similar question with similar replies.

    0 讨论(0)
  • 2021-01-04 07:40

    Another procedure is to change the behavior of document.write() function.
    Assume you have the main index.php file:

    <html>
    <head>
    <meta charset="utf-8" />
    </head>
    <body>
    Hello<br>
    <div id="target"></div>
    <script>
    document.write = function(input) {
        document.body.innerHTML += input;
    }
    var doit = function() {
        var script_tag = document.createElement('script');
        script_tag.type = 'text/javascript';
        script_tag.src="http://127.0.0.1:8080/testPlace/jsfile.js";
        document.getElementById('target').appendChild(script_tag);
    }
    </script>
    </body>
    </html>
    

    and the jsfile.js is like this:

    document.write("OK MAN!");
    

    now if you type doit() in the js browser console to execute that function (and the script do what you wrote) then the result would be:

    Hello
    OK MAN!
    

    In which the html is like this:

    <html><head>
    <meta charset="utf-8">
    </head>
    <body>
    Hello<br>
    <div id="target"><script src="http://127.0.0.1:8080/testPlace/jsfile.js" type="text/javascript"></script></div>
    <script>
        //That Script which here I removed it to take less space in answer
    </script>
    
    OK MAN!</body>
    </html>
    
    0 讨论(0)
提交回复
热议问题