在頁面加載之后執(zhí)行JavaScript
我們都知道,頁面加載是有順序的。讓我們先來理一下頁面的展示過程:
當(dāng)你輸入url并按下回車時(shí)
- 首先從本地查找域名,有的話直接用hosts文件里的ip地址,否則查詢DNS,得到ip地址
- 建立TCP連接——進(jìn)行“三次握手”
- 客戶端發(fā)送http請(qǐng)求
- 服務(wù)端處理,并返回結(jié)果給客戶端
- 關(guān)閉TCP連接——需要“四次揮手”
- 瀏覽器收到結(jié)果,開始解析資源(JS、CSS、HTML),解析HTML生成的dom樹,和同時(shí)解析css生成的cssom樹結(jié)合生成渲染樹
- 根據(jù)渲染樹渲染頁面
當(dāng)然,再詳細(xì)的比如:如何解析生成DOM樹、瀏覽器在三次握手四次揮手的同時(shí)做了什么、CSSOM樹是怎么和DOM樹 一一對(duì)應(yīng)的… 這些如果你不是在做系統(tǒng),似乎是無關(guān)緊要的 —— 至少對(duì)本文來說是這樣的。
經(jīng)過上面的步驟,瀏覽器已經(jīng)拿到了想要的結(jié)果,下一步:瀏覽器渲染進(jìn)程啟用多個(gè)線程協(xié)助完成頁面渲染
- GUI渲染線程 ,負(fù)責(zé)渲染瀏覽器界面,解析HTML、css,構(gòu)建DOM樹和RenderObject樹,布局和繪制 ——一旦界面因?yàn)槟撤N操作引發(fā)了回流,此線程就會(huì)執(zhí)行
- JS引擎線程 ——和GUI線程互斥,在js引擎執(zhí)行時(shí),GUI線程被掛起
- 事件觸發(fā)線程 ——依賴js的隊(duì)列機(jī)制完成(當(dāng)一個(gè)事件觸發(fā)時(shí)該線程會(huì)把事件添加到待處理隊(duì)列的隊(duì)尾,等待js引擎處理)
- 定時(shí)器觸發(fā)線程 ——依賴js的隊(duì)列機(jī)制完成
- 異步http請(qǐng)求線程
這其中有一個(gè)重要的地方:JavaScript執(zhí)行線程和渲染線程互斥 !而且JavaScript線程的優(yōu)先級(jí)最高!
所以一旦在HTML中發(fā)現(xiàn)了<script>
,瀏覽器便會(huì)暫停其余HTML元素的顯示轉(zhuǎn)而去“馬上加載JS代碼”,這可能會(huì)導(dǎo)致兩個(gè)問題的發(fā)生:
- 頁面「一片空白」
- 報(bào)錯(cuò) —— JS無法訪問未知(還沒開始的)加載內(nèi)容
所以,我們需要一種方法來“暫停”JS執(zhí)行。
很多人第一時(shí)間會(huì)選擇 window.onload
:恕我直言,這確實(shí)不是好的方法,它讓用戶等的太久了。你稍微一查就能知道:onload方法會(huì)等待頁面上所有的文字、table、img加載完成后才觸發(fā)。如果你真的要用,筆者倒是更推薦 DOMContentLoaded
,這個(gè)onload的“變異產(chǎn)品”會(huì)等到文字加載完成后立即觸發(fā) —— 你完全不必考慮圖片的大小對(duì)頁面初始加載時(shí)間的影響,如果你不會(huì)“調(diào)用”圖片的話(前面說了,JS無法訪問未知加載內(nèi)容)。
但事實(shí)上,我們更需要一種方法,讓JS在“瀏覽器獲得內(nèi)容后、真正展示在屏幕上前”就開始執(zhí)行。
比較幸運(yùn)(也可能是不幸)的是,jQuery實(shí)現(xiàn)了這個(gè)方法:
$(document).ready(function(){ //... })
不過據(jù)說jQuery的ready和原生JS的DOMContentLoaded效果是一樣的:網(wǎng)頁中所有 DOM 結(jié)構(gòu)繪制完畢后就執(zhí)行(可能 DOM 元素關(guān)聯(lián)的內(nèi)容并沒有加載完)
除此之外,JS中的 window.onload 和jQuery中的$(window).load()
是等價(jià)的
哦,這里并不是“盲目推崇”jQuery,你完全可以去自己封裝一個(gè)。比如 jQuery的 ready()
和JS的 DOMContentLoaded
實(shí)際上都實(shí)現(xiàn)了(或“基于”)這樣一段代碼:
function init(){ if(arguments.callee.done) return; arguments.callee.done=true; if(timer) clearInterval(timer); //... } //判斷瀏覽器 //針對(duì)Mozilla/Opera9 if(document.addEventListener){ document.addEventListener('DOMContentLoaded',init,false) } //針對(duì)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() //調(diào)用加截處理器 }; } //針對(duì)Safari if (/WebKit/i.test(navigator.userAgent)) { var timer = setinterval( function (){ if( /loaded | complete/.test(document.readyState)) { init() //調(diào)用加載處理器 } }. 10); //針對(duì)其他瀏覽器 window.onload = init;
到此這篇關(guān)于在頁面加載之后執(zhí)行JavaScript的文章就介紹到這了,更多相關(guān)頁面加載后執(zhí)行js內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript獲取文檔坐標(biāo)和視口坐標(biāo)
制作網(wǎng)頁的過程中,你有時(shí)候需要知道某個(gè)元素在網(wǎng)頁上的確切位置。下面的教程總結(jié)了Javascript在網(wǎng)頁定位方面的相關(guān)知識(shí)。有需要的小伙伴可以參考下。2015-05-05javascript實(shí)現(xiàn)動(dòng)態(tài)統(tǒng)計(jì)圖開發(fā)實(shí)例
這篇文章主要介紹了javascript實(shí)現(xiàn)動(dòng)態(tài)統(tǒng)計(jì)圖開發(fā)實(shí)例,需要的朋友可以參考下2015-11-11JS控件autocomplete 0.11演示及下載 1月5日已更新
JS控件autocomplete 0.11演示及下載 1月5日已更新...2007-01-01JavaScript中高級(jí)語法??表達(dá)式用法示例詳解
這篇文章主要為大家介紹了JavaScript中高級(jí)語法??表達(dá)式用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04