Rewrite document.write to implement non-blocking loading JS advertising (supplemental) _javascript Tips

Source: Internet
Author: User

Non-blocking loading JavaScript, for page performance optimization has a great effect, this can effectively reduce the blocking of the page load JS. In particular, some ads JS file, because the advertising content may be rich media, it is likely to become your page load speed bottleneck, high-performance JavaScript tells us, students, improve your Web page speed, the load JS without blocking.

So then there is the code appears.

(function () {
var s = document.createelement (' script ');
S.type = ' text/javascript ';
S.async = true;
S.SRC = ' http://yourdomain.com/script.js ';
var x = document.getelementsbytagname (' script ') [0];
X.parentnode.insertbefore (S, x);
}) ();

The above are all familiar, read the students know that this is not blocking the benefits of loading, the effect is very good, when this non-blocking script encountered general JS ads to write the problem--advertising code appears in the HTML but does not display ads.

Nani? Does the HTML come out and not render to the page?

First look at the ads JS code

Copy Code code as follows:

document.write ('

The code is very simple on a document.write output HTML code (believe that many advertisers are such ads), the page does not show the advertising problem where? The problem is in this document.write. Why? First W3Schools see the definition of document.write is very used.

Definitions and usage
the Write () method writes an HTML expression or JavaScript code to the document.
You can list multiple parameters (Exp1,exp2,exp3,...) that are appended to the document in order.

Method:
One is to use the party to output HTML in the document, and the other is to produce a new document in a window, frame, outside the window where the method is invoked. In the second case, be sure to use the close () method to turn off the document.

But the principle is to execute in the page flow input process, once the page is loaded, call document.write () again, implicitly call Document.open () to erase the current document and start a new document. That is, if we use document.write after the HTML is loaded, we will erase the HTML generated before and display the contents of the document.write output.

In our example, when the page is loaded in HTML, the output document.write is not executed. The question knows, the principle knows, that how solves this question?

Asynchronous use of Ajax, row different, a lot of advertising files are third-party, under different domain names, there is a cross-domain problem, and we can not control the output of its code. In this case we think of a way to rewrite the document.write, in the JS file after the load is finished and then rewrite the document.write back. Look at the code.

The first version of non-blocking loading JS ads:

function loadadscript (URL, container, callback) {THIS.DW = document.write;
    This.url = URL;
    This.containerobj = (typeof container = = ' string '? document.getElementById (Container): container); This.callback = Callback | |
  function () {};
        } Loadadscript.prototype = {startload:function () {var script = document.createelement (' script '),
      
      _this = this; if (script.readystate) {//ie script.onreadystatechange = function () {if (script.readystate = = "Loaded" | | s
          Cript.readystate = = "complete") {script.onreadystatechange = null;
        _this.finished ();
      }
      };
        }else{//other script.onload = function () {_this.finished ();
      };
        } document.write = function (AD) {var html = _this.containerobj.innerhtml;
      _this.containerobj.innerhtml = html + ad;
      } script.src = _this.url;
      Script.type = ' Text/javascript '; Document.getelementSbytagname (' head ') [0].appendchild (script);
      }, Finished:function () {document.write = THIS.DW;
    This.callback.apply (); }
  };

Page Call Code:

var loadscript = new Loadadscript (' ad.js ', ' msat-adwrap ', function () {console.log (' msat-adwrap ');});
  Loadscript.startload ();
  
  var loadscript = new Loadadscript (' ad2.js ', ' msat-adwrap ', function () {console.log (' msat-adwrap2 ');});
  Loadscript.startload ();
  
  var loadscript = new Loadadscript (' ad3.js ', ' msat-adwrap ', function () {console.log (' msat-adwrap3 ');});
  Loadscript.startload ();

Ad JS Code

Ad.js
document.write ('  ");

Ad2.js document.write ('  " );

Ad3.js
document.write ('  ');

The problem with the first version is that there are some problems when multiple file calls occur:

1. Because the speed of the file loading is not the same, resulting in some of the load may be loaded before loading, that is, disorderly, and many times we need is orderly. For example, we need to load first screen ads first.

2. Some ads need to set some parameters before, such as Google AdSense

In order to solve these two problems to further modify into the final non-blocking load JS version.

HTML page code:

<! DOCTYPE html>  

Loadscript.js Source code

/** * Non-blocking load advertisement * @author arain.yu/var Loadscript = (function () {var adqueue = [], DW = document.write;
    Cache JS's own document.write function loadadscript (URL, container, init, callback) {this.url = URL;
    This.containerobj = (typeof container = = ' string '? document.getElementById (Container): container);
    This.init = Init | |


    function () {};
    This.callback = Callback | |

  function () {};  } Loadadscript.prototype = {startload:function () {var script = document.createelement (' script '), _this =

      This

      _this.init.apply ();  if (script.readystate) {//ie script.onreadystatechange = function () {if (script.readystate = = "Loaded" | |
            Script.readystate = = "complete") {script.onreadystatechange = null;
          _this.startnext ();
      }
        };
        else {//other script.onload = function () {_this.startnext ();
      }; }//Rewrite document.write documenT.write = function (AD) {var html = _this.containerobj.innerhtml;
      _this.containerobj.innerhtml = html + ad;
      } script.src = _this.url;
      Script.type = ' Text/javascript ';
    document.getElementsByTagName (' head ') [0].appendchild (script);
    }, Finished:function () {//restore document.write document.write = THIS.DW;
      }, Startnext:function () {adqueue.shift ();
      This.callback.apply ();
      if (Adqueue.length > 0) {adqueue[0].startload ();
      else {this.finished ();

  }
    }
  };

      return {add:function (adobj) {if (!adobj) return;
      Adqueue.push (New Loadadscript (Adobj.url, Adobj.container, Adobj.init, Adobj.callback));
    return this;
      }, Execute:function () {if (Adqueue.length > 0) {adqueue[0].startload ();
}
    }
  }; }());

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.