亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在滾動時替換粘性元素?

如何在滾動時替換粘性元素?

翻翻過去那場雪 2024-01-18 17:02:55
語境我正在制作一個博客網站,我希望有一個粘性元素,該元素會隨著用戶滾動而在每個新的一年和月份進行更新。這樣標題就會顯示列出的博客文章的當前月份和年份。編碼的時候,我嘗試用HTML實現效果,如果不行就用CSS,如果還是不行就用JS。我相信這是一個很好的做法,因為它使用內置功能并減少了所需的計算資源,但如果您不同意這個觀點,請告訴我。問題理想情況下,元素的樣式在“卡住”時會發生變化。為此,我查看了David Walsh 的解決方案,該解決方案使用IntersectionObserver但在添加多個元素時會出現故障。我面臨的主要問題是,當有多個條目時,腳本會將位于窗口底部邊框的元素檢測為“固定”。代碼這是一個片段。我還用相同的代碼制作了一個jsfiddle 。//Essentially putting David Walsh's code in a loopdocument.querySelectorAll(".myElement").forEach((i) => {const observer = new IntersectionObserver(([i]) => i.target.classList.toggle("is-pinned", i.intersectionRatio < 1),{threshold: [1]});observer.observe(i);})#parent {   height: 2000px; }.myElement {  position: sticky;  top: -1px;}/* styles for when the header is in sticky mode. The transition times accentuate the undesired effect */.myElement.is-pinned {  color: red;  transition: color 0.3s, background-color 0.3s;  background-color: orange;}<div id="parent">  <!-- Adding more than one 'hello' element. The br's are here to add vertical space and be longer than the viewport height -->  <br><br><br><br>  <div class="myElement">Hello!</div>    <br><br><br><br>  <div class="myElement">Hello 2!</div>    <br><br><br><br>  <div class="myElement">Hello 3!</div>    <br><br><br><br>  <div class="myElement">Hello 4!</div>    <br><br><br><br>  <div class="myElement">Hello 5!</div>    <br><br><br><br>  <div class="myElement">Hello 6!</div>    <br><br><br><br>  <div class="myElement">Hello 7!</div>    <br><br><br><br>  <div class="myElement">Hello 8!</div></div>
查看完整描述

2 回答

?
開心每一天1111

TA貢獻1836條經驗 獲得超13個贊

首先,你只需要一個?IntersectionObserver。只要您需要相同的回調和選項(在本例中就是如此),您就可以observe()使用同一個觀察者來處理多個元素。只有您observer.observe(i);需要在循環內。

但是,如果您向上或向下跳轉頁面,則您的單個觀察者可以同時調用多個條目。因此,您需要循環所有觀察到的條目。

更重要的是,intersectionRatio不關心元素在屏幕上的位置。元素在框的頂部和底部都跨越了 100% 可見性閾值。

您只關心框頂部的元素。該IntersectionObserverEntry對象還有一個boundingClientRect屬性可以告訴您該元素現在所在的位置。您可以使用它來僅切換頂部的元素。

所以你最終會得到這樣的結果:

const observer = new IntersectionObserver((entries) => {

? ? for (let i of entries) {

? ? ? ? i.target.classList.toggle(

? ? ? ? ? ? "is-pinned", i.boundingClientRect.y < 0);

? ? }

}, {threshold: [1]});


document.querySelectorAll(".myElement").forEach(i => observer.observe(i));

然而,這仍然給你帶來了一個問題。在您的示例中,您滾動的框足夠長,如果您直接從頂部跳到底部,則會出現從“框下方可見 0%”到“框頂部可見 99%”的元素。這不會超過 100% 閾值,因此 IntersectionObserver 回調永遠不會為這些元素觸發!這意味著他們沒有上課is-pinned。


您可以簡單地向同一個觀察者添加另一個 0% 的閾值來捕獲這些變化:


const observer = new IntersectionObserver((entries) => {

? ? for (let i of entries) {

? ? ? ? i.target.classList.toggle(

? ? ? ? ? ? "is-pinned", i.boundingClientRect.y < 0);

? ? }

}, {threshold: [0, 1]});


document.querySelectorAll(".myElement").forEach(i => observer.observe(i));

現在,從可見到粘性(或反之亦然)的元素和從不可見到粘性(或反之亦然)的元素都會切換其類。


查看完整回答
反對 回復 2024-01-18
?
MMMHUHU

TA貢獻1834條經驗 獲得超8個贊

你的JS最后一行犯了一個錯誤。將其更改為:


document.querySelectorAll(".myElement").forEach((i) => {

  const observer = new IntersectionObserver(

  ([i]) => i.target.classList.toggle("is-pinned", i.intersectionRatio < 1), {

    threshold: [1]

  });

  observer.observe(document.querySelector(".myElement")); // Use the element instead!

})


查看完整回答
反對 回復 2024-01-18
  • 2 回答
  • 0 關注
  • 146 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號