Deferrable [removed]

2019-07-05 03:02发布

问题:

alot of web advertising providers use the old document.write method, in my case AdTech. Is it possible to overwrite the document.write method to defer after the onload event?

回答1:

How about using either

  • writecapture (https://github.com/iamnoah/writeCapture) an utility to assist the Ajax loading of HTML containing script tags that use document.write or
  • PostsScribe (https://github.com/krux/postscribe/) which lets you deliver a synchronous ad asynchronously without modifying the ad code.


回答2:

Moving all your scripts to the bottom of the page (before >/body<) with advert scripts absolutely last and not using domReady at all (don't need it if your scripts are put in after all HTML elements) will do the same thing. In fact, it might be possible that defering document.write calls can even ruin the entire page depending on how aweful the advert code is.



回答3:

you can output a

document.old_write=document.write;
window._bufferedText='';
document.write=function(text) {
    window._bufferedText+=text;
}
//now let all the document.write go here
document.write('<h1>');
document.write('Hello World!');
document.write('</h1>');
//alert(window._bufferedText);
//end document.write methods
document.write=document.old_write;
document.write('<div id="deferred-write-placeholder"></div>');

window.onload=function() {
    document.getElementById('deferred-write-placeholder').innerHTML=window._bufferedText;
    delete window._bufferedText;
}

Notes:

  • you can rewrite something more complex to handle all instances of document.write code chunks.
  • you should replace window.onload with your javascript framework specific onload handler.


回答4:

You can actually support script injection the correct way by intercepting calls to document.write as follows. The trick is to create a "middleman" function which checks inputs to document.write, and if it's a script tag being injected, load it correctly into the DOM instead:

document.writeText = document.write;

document.write = function(parameter) {
    if (!parameter) return; 
    var scriptPattern = /<script.*?src=['|"](.*?)['|"]/;
    if (scriptPattern.test(parameter)) {
        var srcAttribute = scriptPattern.exec(parameter)[1];
        var script = document.createElement('script');
        script.src = srcAttribute;
        document.head.appendChild(script); 
    }
    else {
        document.writeText(parameter);
    }   
};

Obviously this can be condensed down a bit further, but the variable names are included for clarity. If you like, you can follow up by using async and defer on the script tag loading the third-party library itself, making sure to test for correctness after such a change.

Source