在頁面加載之後執行JavaScript
我們都知道,頁面加載是有順序的。讓我們先來理一下頁面的展示過程:
當你輸入url並按下回車時
- 首先從本地查找域名,有的話直接用hosts文件裡的ip地址,否則查詢DNS,得到ip地址
- 建立TCP連接——進行“三次握手”
- 客戶端發送http請求
- 服務端處理,並返回結果給客戶端
- 關閉TCP連接——需要“四次揮手”
- 瀏覽器收到結果,開始解析資源(JS、CSS、HTML),解析HTML生成的dom樹,和同時解析css生成的cssom樹結合生成渲染樹
- 根據渲染樹渲染頁面
當然,再詳細的比如:如何解析生成DOM樹、瀏覽器在三次握手四次揮手的同時做瞭什麼、CSSOM樹是怎麼和DOM樹 一一對應的… 這些如果你不是在做系統,似乎是無關緊要的 —— 至少對本文來說是這樣的。
經過上面的步驟,瀏覽器已經拿到瞭想要的結果,下一步:瀏覽器渲染進程啟用多個線程協助完成頁面渲染
- GUI渲染線程 ,負責渲染瀏覽器界面,解析HTML、css,構建DOM樹和RenderObject樹,佈局和繪制 ——一旦界面因為某種操作引發瞭回流,此線程就會執行
- JS引擎線程 ——和GUI線程互斥,在js引擎執行時,GUI線程被掛起
- 事件觸發線程 ——依賴js的隊列機制完成(當一個事件觸發時該線程會把事件添加到待處理隊列的隊尾,等待js引擎處理)
- 定時器觸發線程 ——依賴js的隊列機制完成
- 異步http請求線程
這其中有一個重要的地方:JavaScript執行線程和渲染線程互斥 !而且JavaScript線程的優先級最高!
所以一旦在HTML中發現瞭<script>
,瀏覽器便會暫停其餘HTML元素的顯示轉而去“馬上加載JS代碼”,這可能會導致兩個問題的發生:
- 頁面「一片空白」
- 報錯 —— JS無法訪問未知(還沒開始的)加載內容
所以,我們需要一種方法來“暫停”JS執行。
很多人第一時間會選擇 window.onload
:恕我直言,這確實不是好的方法,它讓用戶等的太久瞭。你稍微一查就能知道:onload方法會等待頁面上所有的文字、table、img加載完成後才觸發。如果你真的要用,筆者倒是更推薦 DOMContentLoaded
,這個onload的“變異產品”會等到文字加載完成後立即觸發 —— 你完全不必考慮圖片的大小對頁面初始加載時間的影響,如果你不會“調用”圖片的話(前面說瞭,JS無法訪問未知加載內容)。
但事實上,我們更需要一種方法,讓JS在“瀏覽器獲得內容後、真正展示在屏幕上前”就開始執行。
比較幸運(也可能是不幸)的是,jQuery實現瞭這個方法:
$(document).ready(function(){ //... })
不過據說jQuery的ready和原生JS的DOMContentLoaded效果是一樣的:網頁中所有 DOM 結構繪制完畢後就執行(可能 DOM 元素關聯的內容並沒有加載完)
除此之外,JS中的 window.onload 和jQuery中的$(window).load()
是等價的
哦,這裡並不是“盲目推崇”jQuery,你完全可以去自己封裝一個。比如 jQuery的 ready()
和JS的 DOMContentLoaded
實際上都實現瞭(或“基於”)這樣一段代碼:
function init(){ if(arguments.callee.done) return; arguments.callee.done=true; if(timer) clearInterval(timer); //... } //判斷瀏覽器 //針對Mozilla/Opera9 if(document.addEventListener){ document.addEventListener('DOMContentLoaded',init,false) } //針對IE document.write ("<script id='__ie_onload defer' src='javascript:void(O);'><\/script>" ); var script = document.getElementById("__ie_onload"); script.onreadystatechange = function() { if( this.readyState == " complete" ) { init() //調用加截處理器 }; } //針對Safari if (/WebKit/i.test(navigator.userAgent)) { var timer = setinterval( function (){ if( /loaded | complete/.test(document.readyState)) { init() //調用加載處理器 } }. 10); //針對其他瀏覽器 window.onload = init;
到此這篇關於在頁面加載之後執行JavaScript的文章就介紹到這瞭,更多相關頁面加載後執行js內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- JavaScript之BOM構成和常用事件詳解
- JavaScript DOMContentLoaded事件案例詳解
- JavaScript 文件加載與阻塞問題之性能優化案例詳解
- JavaScript必看的10道面試題總結(推薦)
- javascript實現圖片預加載和懶加載