在頁(yè)面加載之后執(zhí)行JavaScript
我們都知道,頁(yè)面加載是有順序的。讓我們先來(lái)理一下頁(yè)面的展示過(guò)程:
當(dāng)你輸入url并按下回車(chē)時(shí)
- 首先從本地查找域名,有的話直接用hosts文件里的ip地址,否則查詢DNS,得到ip地址
- 建立TCP連接——進(jìn)行“三次握手”
- 客戶端發(fā)送http請(qǐng)求
- 服務(wù)端處理,并返回結(jié)果給客戶端
- 關(guān)閉TCP連接——需要“四次揮手”
- 瀏覽器收到結(jié)果,開(kāi)始解析資源(JS、CSS、HTML),解析HTML生成的dom樹(shù),和同時(shí)解析css生成的cssom樹(shù)結(jié)合生成渲染樹(shù)
- 根據(jù)渲染樹(shù)渲染頁(yè)面
當(dāng)然,再詳細(xì)的比如:如何解析生成DOM樹(shù)、瀏覽器在三次握手四次揮手的同時(shí)做了什么、CSSOM樹(shù)是怎么和DOM樹(shù) 一一對(duì)應(yīng)的… 這些如果你不是在做系統(tǒng),似乎是無(wú)關(guān)緊要的 —— 至少對(duì)本文來(lái)說(shuō)是這樣的。
經(jīng)過(guò)上面的步驟,瀏覽器已經(jīng)拿到了想要的結(jié)果,下一步:瀏覽器渲染進(jìn)程啟用多個(gè)線程協(xié)助完成頁(yè)面渲染
- GUI渲染線程 ,負(fù)責(zé)渲染瀏覽器界面,解析HTML、css,構(gòu)建DOM樹(shù)和RenderObject樹(shù),布局和繪制 ——一旦界面因?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è)問(wèn)題的發(fā)生:
- 頁(yè)面「一片空白」
- 報(bào)錯(cuò) —— JS無(wú)法訪問(wèn)未知(還沒(méi)開(kāi)始的)加載內(nèi)容
所以,我們需要一種方法來(lái)“暫停”JS執(zhí)行。
很多人第一時(shí)間會(huì)選擇 window.onload :恕我直言,這確實(shí)不是好的方法,它讓用戶等的太久了。你稍微一查就能知道:onload方法會(huì)等待頁(yè)面上所有的文字、table、img加載完成后才觸發(fā)。如果你真的要用,筆者倒是更推薦 DOMContentLoaded ,這個(gè)onload的“變異產(chǎn)品”會(huì)等到文字加載完成后立即觸發(fā) —— 你完全不必考慮圖片的大小對(duì)頁(yè)面初始加載時(shí)間的影響,如果你不會(huì)“調(diào)用”圖片的話(前面說(shuō)了,JS無(wú)法訪問(wèn)未知加載內(nèi)容)。
但事實(shí)上,我們更需要一種方法,讓JS在“瀏覽器獲得內(nèi)容后、真正展示在屏幕上前”就開(kāi)始執(zhí)行。
比較幸運(yùn)(也可能是不幸)的是,jQuery實(shí)現(xiàn)了這個(gè)方法:
$(document).ready(function(){
//...
})不過(guò)據(jù)說(shuō)jQuery的ready和原生JS的DOMContentLoaded效果是一樣的:網(wǎng)頁(yè)中所有 DOM 結(jié)構(gòu)繪制完畢后就執(zhí)行(可能 DOM 元素關(guān)聯(lián)的內(nèi)容并沒(mé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)于在頁(yè)面加載之后執(zhí)行JavaScript的文章就介紹到這了,更多相關(guān)頁(yè)面加載后執(zhí)行js內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)二級(jí)菜單點(diǎn)擊顯示當(dāng)前內(nèi)容效果
這篇文章主要介紹了js實(shí)現(xiàn)二級(jí)菜單點(diǎn)擊顯示當(dāng)前內(nèi)容效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
layui table checked獲取選中數(shù)據(jù)方式
這篇文章主要介紹了layui table checked獲取選中數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
js使用文件流下載csv文件的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于js使用文件流下載csv文件的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
js canvas實(shí)現(xiàn)畫(huà)圖、濾鏡效果
這篇文章主要為大家詳細(xì)介紹了js canvas實(shí)現(xiàn)畫(huà)圖、濾鏡效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
查找頁(yè)面中所有類(lèi)為test的結(jié)點(diǎn)的方法
這篇文章主要介紹了查找頁(yè)面中所有類(lèi)為test結(jié)點(diǎn)的方法,需要的朋友可以參考下2014-03-03
javascript中關(guān)于執(zhí)行環(huán)境的雜談
如你所知,javascript里執(zhí)行環(huán)境是作為一個(gè)最核心的概念存在的。相信廣大FE筒子們對(duì)于這個(gè)概念不會(huì)陌生,它定義了變量或函數(shù)有權(quán)訪問(wèn)其他數(shù)據(jù)范圍以及其行為。2011-08-08

