国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

重寫document.write實現無阻塞加載js廣告(補充)

2024-05-06 16:11:56
字體:
來源:轉載
供稿:網友

這篇文章主要介紹了重寫document.write實現無阻塞加載js廣告,需要的朋友可以參考下

無阻塞加載javascript,對于頁面性能優化有很大的作用,這樣能有效的減少js對頁面加載的阻塞。特別是一些廣告js文件,由于廣告內容有可能是富媒體,更是很可能成為你頁面加載提速的瓶頸,高性能javascript告訴我們,同學,提升你的網頁速度,就無阻塞地加載JS吧。

于是便有一下代碼出現。
 

  1. (function() { 
  2. var s = document.createElement('script'); 
  3. s.type = 'text/javascript'
  4. s.async = true
  5. s.src = 'http://yourdomain.com/script.js'
  6. var x = document.getElementsByTagName('script')[0]; 
  7. x.parentNode.insertBefore(s, x); 
  8. })(); 

上邊都是大家熟悉的,看過書的同學都知道這樣無阻塞加載的好處,效果挺不錯的,當此等無阻塞腳本遇到一般js廣告就來了寫問題——廣告代碼出現在HTML里面了卻不顯示廣告。

 

納尼?HTML出來了不渲染到頁面上?

先看看廣告js代碼

復制代碼代碼如下:


 

  1. document.write('<img src="http://www.survivalescaperooms.com/logo_small.gif" alt="Logo">'); 

代碼挺簡單就一個document.write輸出HTML代碼(相信很多廣告商的廣告都這樣),頁面不顯示廣告問題在哪里呢? 問題就在這個document.write。為什么?先w3schools看看document.write的定義很使用吧。

定義和用法

write() 方法可向文檔寫入 HTML 表達式或 JavaScript 代碼。

可列出多個參數(exp1,exp2,exp3,...) ,它們將按順序被追加到文檔中。

方法:

一是在使用該方在文檔中輸出 HTML,另一種是在調用該方法的的窗口之外的窗口、框架中產生新文檔。在第二種情況中,請務必使用 close() 方法來關閉文檔。

但其原理是在頁面流輸入過程中執行,一旦頁面加載完畢,再次調用 document.write(),會隱式地調用 document.open() 來擦除當前文檔并開始一個新的文檔。也就是說如果在HTML加載完后我們再使用document.write會檫除之前生成html,而顯示document.write輸出的內容。

而我們例子中在頁面加載完后在在html中輸出document.write,就不會被執行了。問題知道了,原理知道了,那怎么解決這個問題呢?

異步利用ajax,行不同,很多廣告文件都是第三方的,在不同域名下,存在跨域問題,而且不能我們控制其代碼的輸出。在這種情況下我們想到了一個辦法就是重寫掉document.write,在js文件加載結束后再把document.write重寫回去。看代碼。

第一版本無阻塞加載js廣告:

  1. function LoadADScript(url, container, callback){ 
  2. this.dw = document.write; 
  3. this.url = url; 
  4. this.containerObj = (typeof container == 'string'?document.getElementById(container):container); 
  5. this.callback = callback || function(){}; 
  6.  
  7. LoadADScript.prototype = { 
  8. startLoad: function(){ 
  9. var script = document.createElement('script'), 
  10. _this = this
  11.  
  12. if(script.readyState){ //IE 
  13. script.onreadystatechange = function(){ 
  14. if (script.readyState == "loaded" || script.readyState == "complete"){ 
  15. script.onreadystatechange = null
  16. _this.finished(); 
  17. }; 
  18. }else//Other 
  19. script.onload = function(){ 
  20. _this.finished(); 
  21. }; 
  22.  
  23. document.write = function(ad){ 
  24. var html = _this.containerObj.innerHTML; 
  25. _this.containerObj.innerHTML = html + ad; 
  26.  
  27. script.src = _this.url; 
  28. script.type = 'text/javascript'
  29. document.getElementsByTagName('head')[0].appendChild(script); 
  30. }, 
  31. finished: function(){ 
  32. document.write = this.dw; 
  33. this.callback.apply(); 
  34. }; 


頁面調用代碼:

  1. var loadScript = new LoadADScript('ad.js','msat-adwrap',function(){ console.log('msat-adwrap'); }); 
  2. loadScript.startLoad(); 
  3.  
  4. var loadScript = new LoadADScript('ad2.js','msat-adwrap',function(){ console.log('msat-adwrap2'); }); 
  5. loadScript.startLoad(); 
  6.  
  7. var loadScript = new LoadADScript('ad3.js','msat-adwrap',function(){ console.log('msat-adwrap3'); }); 
  8. loadScript.startLoad(); 


廣告js代碼

  1. //ad.js 
  2. document.write('<img src="http://images.cnblogs.com/logo_small.gif" alt="Logo">'); 
  3.  
  4. //ad2.js 
  5. document.write('<img src="http://www.baidu.com/img/baidu_sylogo1.gif" width="270" height="129" usemap="#mp">'); 
  6.  
  7. //ad3.js 
  8. document.write('<img alt="Google" height="95" id="hplogo" src="http://www.google.com/images/srpr/logo3w.png" width="275">'); 


第一版本的問題是在多個文件調用的時候,會出現一些問題:

1. 由于文件加載的速度不一樣,導致可能有些先加載有些后加載,也就是無序的,而且很多時候我們需要的是有序的。比如我們需要先加載第一屏的廣告。

2. 想有些廣告需要前置設置一些參數的,例如google adsense

為了解決這兩個問題好進一步修改成最終無阻塞加載js版本。

HTML頁面代碼:

 


  1. <!DOCTYPE html> 
  2. <html lang="en"
  3. <head> 
  4. <meta charset="utf-8" /> 
  5. <title>new_file</title> 
  6. <script type="text/javascript" src="loadscript.js"></script> 
  7. </head> 
  8. <body> 
  9. <div id = "msat-adwrap"></div> 
  10. <div id = "msat-adwrap2"></div> 
  11. <script type="text/javascript"
  12. loadScript.add({ 
  13. url:'ad.js'
  14. container: 'msat-adwrap'
  15. callback:function(){ console.log('msat-adwrap'); } 
  16. }).add({ 
  17. url:'ad2.js'
  18. container: 'msat-adwrap2'
  19. callback:function(){ console.log('msat-adwrap2'); } 
  20. }).add({//google adsense 
  21. url:'http://pagead2.googlesyndication.com/pagead/show_ads.js'
  22. container: 'msat-adwrap'
  23. init: function(){ 
  24. google_ad_client = "ca-pub-2152294856721899"
  25. /* 250x250 rich */ 
  26. google_ad_slot = "3929903770"
  27. google_ad_width = 250; 
  28. google_ad_height = 250; 
  29. }, 
  30. callback:function(){ console.log('msat-adwrap3'); } 
  31. }).execute(); 
  32. </script> 
  33. </body> 
  34. </html> 

 

loadscript.js源代碼

  1. /** 
  2. * 無阻塞加載廣告 
  3. * @author Arain.Yu 
  4. */ 
  5.  
  6. var loadScript = ( function() { 
  7. var adQueue = [], dw = document.write; 
  8. //緩存js自身的document.write 
  9.  
  10. function LoadADScript(url, container, init, callback) { 
  11. this.url = url; 
  12. this.containerObj = ( typeof container == 'string' ? document.getElementById(container) : container); 
  13. this.init = init || 
  14. function() { 
  15. }; 
  16.  
  17.  
  18. this.callback = callback || 
  19. function() { 
  20. }; 
  21.  
  22.  
  23.  
  24. LoadADScript.prototype = { 
  25. startLoad : function() { 
  26. var script = document.createElement('script'), _this = this
  27.  
  28. _this.init.apply(); 
  29.  
  30. if(script.readyState) {//IE 
  31. script.onreadystatechange = function() { 
  32. if(script.readyState == "loaded" || script.readyState == "complete") { 
  33. script.onreadystatechange = null
  34. _this.startNext(); 
  35. }; 
  36. else {//Other 
  37. script.onload = function() { 
  38. _this.startNext(); 
  39. }; 
  40. //重寫document.write 
  41. document.write = function(ad) { 
  42. var html = _this.containerObj.innerHTML; 
  43. _this.containerObj.innerHTML = html + ad; 
  44.  
  45. script.src = _this.url; 
  46. script.type = 'text/javascript'
  47. document.getElementsByTagName('head')[0].appendChild(script); 
  48. }, 
  49. finished : function() { 
  50. //還原document.write 
  51. document.write = this.dw; 
  52. }, 
  53. startNext : function() { 
  54. adQueue.shift(); 
  55. this.callback.apply(); 
  56. if(adQueue.length > 0) { 
  57. adQueue[0].startLoad(); 
  58. else { 
  59. this.finished(); 
  60. }; 
  61.  
  62. return { 
  63. add : function(adObj) { 
  64. if(!adObj) 
  65. return
  66.  
  67. adQueue.push(new LoadADScript(adObj.url, adObj.container, adObj.init, adObj.callback)); 
  68. return this
  69. }, 
  70. execute : function() { 
  71. if(adQueue.length > 0) { 
  72. adQueue[0].startLoad(); 
  73. }; 
  74. }()); 
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 乌什县| 通州市| 平凉市| 安新县| 长子县| 朔州市| 万州区| 威海市| 蒙阴县| 富源县| 建德市| 韶关市| 邛崃市| 钟山县| 隆尧县| 庄河市| 禹城市| 肥西县| 堆龙德庆县| 即墨市| 临桂县| 榆树市| 革吉县| 都昌县| 卫辉市| 云阳县| 开远市| 密云县| 和顺县| 青铜峡市| 长丰县| 吴川市| 远安县| 德惠市| 景德镇市| 富源县| 仁布县| 宁海县| 沐川县| 夏河县| 镇宁|