首页 > 代码库 > document.write()的一些坑

document.write()的一些坑

  这段时间在做一个广告系统,需要用js自动生成广告代码,其中遇到一些问题,在这记录下。

  第三方广告代码一般都是用 document.write()向页面写入,这次使用的时候遇到不少坑,经常会出现使用document.write()向页面写入的时候当前页面被清 空。这正是document.write()的特殊之处,页面载入后浏览器输出流自动关闭。此后对当前页面进行document.write()操作将打 开—个新的输出流,它将清除当前页面内容(包括源文档的任何变量或值)。

  那么有哪些浏览器输出流关闭的标识呢?我们首先想到的是 window.onload,在window.onload后页面加载完成,浏览器输出流必然关闭。经测试$(document).ready()中的操 作也是在浏览器输出流关闭之后执行。所以用于生成代码的document.write()不能写在window.onload 和$(document).ready()中。除了这两个之外有没有其他坑呢?js生成广告代码中需要ajax获取服务端的数据,ajax请求成功之后再 document.write()写入仍然会发生覆盖。这是因为jquery的ajax默认是异步请求,并不阻塞文档流,当ajax请求成功之后在执行操 作,浏览器输出流很可能就关闭了。这种情况可以把ajax默认请求改成同步,阻塞文档流,防止document.write()覆盖。

   由于第三方广告代码使用document.write()输出,所有的广告资源都在页面载入时加载,如果页面上第三方广告比较多,必然会阻塞页面加载。有 没有办法在使用document.write()的情况下不阻塞页面加载呢?其实是可以的,这里就需要我们改造原生的document.write()方 法,在广告加载完毕再把原生方法改回来。这里就不具体展开来写,雨夜带刀博客《让document.write的广告无阻塞的加载》有详细分析,这里贴一下带刀改造document.write()的代码。

 1 /** 2  * 重写document.write实现无阻塞加载script 3  * @param { Dom Object } textarea元素 4  */ 5 var loadScript = function( elem ){ 6     var url = elem.value.match( /src="http://www.mamicode.com/([/s/S]*?)"/i )[1], 7         parent = elem.parentNode, 8         // 缓存原生的document.write 9         docWrite = document.write,    10         // 创建一个新script来加载11         script = document.createElement( ‘script‘ ), 12         head = document.head || 13             document.getElementsByTagName( ‘head‘ )[0] || 14             document.documentElement;15     16     // 重写document.write17     document.write = function( text ){18         parent.innerHTML = text;19     };20 21     script.type = ‘text/javascript‘;22     script.src =http://www.mamicode.com/ url;23     24     script.onerror = 25     script.onload = 26     script.onreadystatechange = function( e ){27         e = e || window.event;28         if( !script.readyState || 29         /loaded|complete/.test(script.readyState) ||30         e === ‘error‘31         ){32 33             // 恢复原生的document.write34             document.write = docWrite;35             head.removeChild( script );36             37             // 卸载事件和断开DOM的引用38             // 尽量避免内存泄漏39             head =             40             parent = 41             elem =42             script = 43             script.onerror = 44             script.onload = 45             script.onreadystatechange = null;46 47         }48     }49     50     // 加载script51     head.insertBefore( script, head.firstChild );52 };

 

document.write()的一些坑