2 回答

TA貢獻(xiàn)1836條經(jīng)驗(yàn) 獲得超13個(gè)贊
首先,你只需要一個(gè)?IntersectionObserver
。只要您需要相同的回調(diào)和選項(xiàng)(在本例中就是如此),您就可以observe()
使用同一個(gè)觀察者來(lái)處理多個(gè)元素。只有您observer.observe(i);
需要在循環(huán)內(nèi)。
但是,如果您向上或向下跳轉(zhuǎn)頁(yè)面,則您的單個(gè)觀察者可以同時(shí)調(diào)用多個(gè)條目。因此,您需要循環(huán)所有觀察到的條目。
更重要的是,intersectionRatio
不關(guān)心元素在屏幕上的位置。元素在框的頂部和底部都跨越了 100% 可見(jiàn)性閾值。
您只關(guān)心框頂部的元素。該IntersectionObserverEntry
對(duì)象還有一個(gè)boundingClientRect
屬性可以告訴您該元素現(xiàn)在所在的位置。您可以使用它來(lái)僅切換頂部的元素。
所以你最終會(huì)得到這樣的結(jié)果:
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));
然而,這仍然給你帶來(lái)了一個(gè)問(wèn)題。在您的示例中,您滾動(dòng)的框足夠長(zhǎng),如果您直接從頂部跳到底部,則會(huì)出現(xiàn)從“框下方可見(jiàn) 0%”到“框頂部可見(jiàn) 99%”的元素。這不會(huì)超過(guò) 100% 閾值,因此 IntersectionObserver 回調(diào)永遠(yuǎn)不會(huì)為這些元素觸發(fā)!這意味著他們沒(méi)有上課is-pinned。
您可以簡(jiǎn)單地向同一個(gè)觀察者添加另一個(gè) 0% 的閾值來(lái)捕獲這些變化:
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));
現(xiàn)在,從可見(jiàn)到粘性(或反之亦然)的元素和從不可見(jiàn)到粘性(或反之亦然)的元素都會(huì)切換其類(lèi)。

TA貢獻(xiàn)1834條經(jīng)驗(yàn) 獲得超8個(gè)贊
你的JS最后一行犯了一個(gè)錯(cuò)誤。將其更改為:
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!
})
添加回答
舉報(bào)