您好,登錄后才能下訂單哦!
最近在做一個(gè)項(xiàng)目的時(shí)候,在safari上遇到了一個(gè)其他的bug,卻讓我意識(shí)到了這個(gè)問題的終極原因。
項(xiàng)目bug是這樣的:我在用Nuxt做一個(gè)展示站點(diǎn),需要使用錨鏈接在頁(yè)面剛進(jìn)入的時(shí)候跳轉(zhuǎn)到某個(gè)位置。這里我本來使用的是router api提供的scrollBehavior方法,但這個(gè)方法在Nuxt上有局限性。我就把實(shí)現(xiàn)方式改為:進(jìn)入頁(yè)面后,動(dòng)態(tài)計(jì)算不同錨點(diǎn)位置的scroll top再設(shè)置父元素的scroll位置。
在其他瀏覽器上都是ok的,但在safari上就出了問題:在頁(yè)面剛進(jìn)入時(shí)無(wú)法正確獲取到元素的scroll top,小很多,只有頁(yè)面加載完成之后才可以。
究其原因,是因?yàn)槲以陧?yè)面上放了很多張圖片讓其自行占位,而在頁(yè)面剛加載時(shí),其他瀏覽器會(huì)預(yù)先獲取到圖片的大小而給其一個(gè)占位,無(wú)論圖片是否加載完成頁(yè)面總高度固定的。而safari就不一樣,圖片沒加載成功時(shí)高度是0。
圖片沒加載成功時(shí)高度是0。哇長(zhǎng)見識(shí)了。
這時(shí)回想到之前在safari上的那個(gè)scroll bug,在查閱相關(guān)資料后就可以得出結(jié)論了:
safari瀏覽器在渲染頁(yè)面元素的時(shí)候,會(huì)預(yù)先走webkit瀏覽器的渲染流程:
構(gòu)建DOM tree
構(gòu)建CSS rule tree
根據(jù)DOM和CSS tree來構(gòu)建render tree
根據(jù)render tree計(jì)算頁(yè)面的layout
注意在第三步和第四步的時(shí)候,safari瀏覽器在構(gòu)建render tree的時(shí)候,會(huì)預(yù)先找到相應(yīng)的overflow: scroll元素,在計(jì)算頁(yè)面layout的時(shí)候,會(huì)計(jì)算父元素的高度與子元素的高度,若子元素高于父元素,則在render頁(yè)面時(shí)為其建立一個(gè)原生的scrollView。
這個(gè)scrollView有什么用的?其實(shí)就是為了給其一個(gè)彈彈樂的效果(但確實(shí)用戶體驗(yàn)不錯(cuò))。
當(dāng)子元素是某個(gè)媒體格式時(shí),比如img、object(svg)等,safari在加載完成之前是不會(huì)在計(jì)算在layout之內(nèi)的,也就是高度為0,則子元素的高度就一定小于父元素的高度,safari不會(huì)給父元素一個(gè)原生的scrollView。
解決辦法
反其道而行之。當(dāng)出現(xiàn)這種問題的時(shí)候,給子元素一個(gè)包裹元素,包裹元素設(shè)置一個(gè)min-height大于父元素的高度,讓父元素有scrollView。當(dāng)子元素加載完成時(shí),將包裹元素?fù)伍_,父元素便可以自由滾動(dòng)了。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。