日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

滚动锚定(Scroll Anchoring)- 让视口内容不再因视口上方 DOM 元素的高度变化而产生跳动

發(fā)布時(shí)間:2023/12/13 综合教程 41 生活家
生活随笔 收集整理的這篇文章主要介紹了 滚动锚定(Scroll Anchoring)- 让视口内容不再因视口上方 DOM 元素的高度变化而产生跳动 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

不知道你有沒有經(jīng)歷過這樣的場景:當(dāng)你打開一張“多圖殺貓”的頁面后,正一張圖一張圖邊滾邊看,在你剛準(zhǔn)備定睛看某一張圖的時(shí)候,這張圖突然被它上面的內(nèi)容擠到了視口下方,然后你趕緊把滾動(dòng)條往下拉,試圖追趕這張沒看完的圖,當(dāng)你剛剛追上的時(shí)候,這張圖又一次被擠到了你看不見的地方。

發(fā)生這種情況的原因是因?yàn)樵诤芏鄨鼍跋拢ū热缯搲铮銢]法事先知道一張圖的高度,所以你沒法事先給這張圖占位,在網(wǎng)速不理想的情況下,可能就會(huì)發(fā)生我上面描述的這種因頁面靠上的圖片比靠下的圖片晚加載出來而導(dǎo)致用戶當(dāng)前瀏覽的內(nèi)容被頻繁擠出視口的情況。

我通過在定時(shí)器回調(diào)里向頁面上方插入圖片來模擬一下剛才描述的這種情況:

<style>
  img {
    display: block;
    margin: 0 auto;
  }
</style>
<img src="https://aecpm.alicdn.com/tfscom/TB1.52aPFXXXXa0XXXXXXXXXXXX.jpg">
<img src="https://aecpm.alicdn.com/tfscom/TB1_utRPVXXXXapXVXXXXXXXXXX.png">
<img src="https://static.dingtalk.com/media/lAHOuOFd_czSzQEn_295_210.gif">
<img src="https://aecpm.alicdn.com/tfscom/TB1f1xwQpXXXXXBXVXXXXXXXXXX.jpg">
<img src="https://gtms03.alicdn.com/tps/i3/TB1eSxvJVXXXXaKXFXXYoAvIXXX-220-50.png">
<img src="https://gw.alicdn.com/bao/uploaded/TB1EGvvPVXXXXX3aXXXXXXXXXXX-200-200.jpg">
<img src="https://gw.alicdn.com/tfscom/TB1CLTHNFXXXXaDXpXXXXXXXXXX">
<script>
  const urls = `
https://asearch.alicdn.com/bao/uploaded/i1/1381306006414474986/TB2_gZAlNtmpuFjSZFqXXbHFpXa_!!0-saturn_solar.jpg
https://asearch.alicdn.com/bao/uploaded/i1/153360285303496277/TB2SO.Wa4vzQeBjSZFEXXbYEpXa_!!0-saturn_solar.jpg
https://asearch.alicdn.com/bao/uploaded/i1/188050339412916381/TB2geTXaypnpuFjSZFkXXc4ZpXa_!!0-saturn_solar.jpg
https://asearch.alicdn.com/bao/uploaded/i2/181720289489216985/TB2UFz6amjz11Bjy0FnXXcnxXXa_!!0-saturn_solar.jpg
https://asearch.alicdn.com/bao/uploaded/i3/108480250457898935/TB28r5osFXXXXbrXXXXXXXXXXXX_!!0-saturn_solar.jpg
https://asearch.alicdn.com/bao/uploaded/i3/111180208599309441/TB2kAsQnVXXXXXcXFXXXXXXXXXX_!!0-saturn_solar.jpg
https://asearch.alicdn.com/bao/uploaded/i3/171530328819399773/TB2rgtke9iK.eBjSZFsXXbxZpXa_!!0-saturn_solar.jpg
https://asearch.alicdn.com/bao/uploaded/i3/1880505035634435666/TB2bToNiHXlpuFjSszfXXcSGXXa_!!0-saturn_solar.jpg
https://asearch.alicdn.com/bao/uploaded/i4/1519305020726924733/TB2I2VuhNhmpuFjSZFyXXcLdFXa_!!0-saturn_solar.jpg
`.split("
")
  let i = 0
  setInterval(() => {
    if (i === urls.length) i = 0
    let img = new Image()
    img.src = urls[i++]
    document.body.prepend(img)
  }, 2000)
  onscroll = function(argument) {
    console.log("scrollY:" + scrollY)
  }
</script>

上面這個(gè) demo 里,假設(shè)我一直“追趕”的那張圖是“金凱瑞搖頭三人組”那張 GIF,那么在 Chrome 56 之前的版本以及在其它的瀏覽器中,你看到的會(huì)是下面這樣的場景:

為了獲得更好的用戶體驗(yàn),Chrome 從 56 開始,開啟了一個(gè)叫做“滾動(dòng)錨定(Scroll Anchoring)”的優(yōu)化,效果就是,當(dāng)頁面在視口上方的部分突然變高了 x 像素,那么瀏覽器會(huì)為你自動(dòng)向下滾動(dòng) x 像素,從而保證視口內(nèi)容完全不變:

瀏覽器自動(dòng)為你向下滾動(dòng) x 像素,就意味著瀏覽器自己會(huì)觸發(fā)一次 scroll 事件,也意味著 scrollY 的值會(huì)增加 x,你可以通過上面的 demo驗(yàn)證這一點(diǎn)。

有些同學(xué)可能會(huì)有疑問,“這種場景多嗎?”、“我怎么從來沒注意到?”、“有必要把事情搞復(fù)雜嗎?”。 從 Chrome 官方的統(tǒng)計(jì)可以看到,這個(gè)特性被觸發(fā)(替你滾動(dòng)頁面)的概率大概為 1%,并不多,但也算不上是極端情況,所以優(yōu)化還是有必要的。可能因?yàn)榻┠昃W(wǎng)絡(luò)條件越來越好,圖片加載的速度比你滾動(dòng)頁面的速度還要快,所以不太容易遇到因網(wǎng)速慢導(dǎo)致的這類場景了(尤其在 WIFI 網(wǎng)絡(luò)下)。

不過這個(gè)優(yōu)化的確不是個(gè)簡單的改動(dòng),Chrome 從去年 3 月份開始實(shí)現(xiàn)這個(gè)特性,直到一年多后的今天,仍然有一些因這個(gè)優(yōu)化導(dǎo)致的 bug 存在,這些 bug 多表現(xiàn)為頁面異常滾動(dòng),甚至像永動(dòng)機(jī)一樣無限抖動(dòng),從這方面看,事情的確有一些被搞的復(fù)雜了。但幸好有一個(gè) CSS 屬性可以關(guān)掉這個(gè)優(yōu)化:overflow-anchor: none,你可以把這個(gè)屬性添加到發(fā)生 bug 的容器元素上,甚至加到 body 元素上也行,然后該元素及其它的所有后代節(jié)點(diǎn)就都不會(huì)被應(yīng)用“滾動(dòng)錨定”的優(yōu)化了。除了作為瀏覽器 bug 的臨時(shí) fix,我想不到其它使用這個(gè)屬性的場景了。

這個(gè)優(yōu)化不僅限于看圖片的時(shí)候,任何元素節(jié)點(diǎn),甚至文本節(jié)點(diǎn)也同樣適用。比如你在某新聞網(wǎng)站瀏覽一段文字的時(shí)候,視口上方突然異步插入了一個(gè)未事先占位的 iframe 廣告(微博輸入框下方就有這么一個(gè)廣告),如果你使用了 Chrome 56 及以上版本的話,你完全察覺不到這一變化,你的閱讀不會(huì)被打斷。

頁面在視口上方的高度增加 x 像素,瀏覽器會(huì)為你向下滾動(dòng) x 像素;反過來,頁面在視口上方的高度減少 x 像素,瀏覽器也會(huì)為你向上滾動(dòng) x 像素,但這種情況更少見了。

該優(yōu)化同樣適用于元素級(jí)別的滾動(dòng)條,我也寫了一個(gè) demo:

<style>
  div {
    width: 300px;
    height: 300px;
  }

  #container {
    background: red;
    overflow: scroll;
  }

  #aboveViewport {
    background: blue;
  }

  #anchorNode {
    background: green;
  }
</style>
<div id="container">
  向下滾動(dòng)到底
  <div id="aboveAnchorNode"></div>
  <div id="anchorNode"></div>
  這段文字一旦出現(xiàn)就會(huì)始終在視口內(nèi)
</div>
<script>
  let height = 100
  setInterval(() => {
    aboveAnchorNode.style.height = height += 10
  }, 1000)
</script>

由于本文講的是一個(gè)瀏覽器的優(yōu)化,即便是前端開發(fā)者也沒有深究的必要,所以我故意省略了一些內(nèi)容,比如什么是錨定節(jié)點(diǎn)(anchor node )以及瀏覽器如何選定一個(gè)錨點(diǎn)節(jié)點(diǎn)?以及哪些樣式改動(dòng)會(huì)把錨定節(jié)點(diǎn)擠出視口但不會(huì)觸發(fā)優(yōu)化(Suppression Triggers),如果你想深究,可以從規(guī)范里找到答案。

總結(jié)

以上是生活随笔為你收集整理的滚动锚定(Scroll Anchoring)- 让视口内容不再因视口上方 DOM 元素的高度变化而产生跳动的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。