Обратный вызов на пересечении наблюдается неоднократно ⇐ Javascript
-
Anonymous
Обратный вызов на пересечении наблюдается неоднократно
import { useEffect, useRef, useState } from "react";
const HEADER_HEIGHT = 64;
const BREADCRUMBS_HEIGHT = 61;
const OFFSET = 0;
function App() {
const stickyRef = useRef(null);
const [isStuck, setIsStuck] = useState(false);
useEffect(() => {
const stickyElement = stickyRef.current as unknown as HTMLDivElement;
if (!stickyElement) return;
const sentinel = document.createElement("div");
sentinel.style.height = "1px";
sentinel.style.position = "absolute";
sentinel.style.top = `${HEADER_HEIGHT + BREADCRUMBS_HEIGHT - OFFSET}px`;
sentinel.style.left = "0";
sentinel.style.right = "0";
sentinel.style.pointerEvents = "none";
sentinel.style.backgroundColor = "red";
sentinel.style.border = "1px dashed red";
sentinel.style.zIndex = "1";
stickyElement.parentNode?.insertBefore(sentinel, stickyElement);
const observer = new IntersectionObserver(
([entry]) => {
setIsStuck(!entry.isIntersecting);
},
{
root: null,
rootMargin: "0px",
threshold: 0,
}
);
observer.observe(sentinel);
return () => {
observer.disconnect();
if (sentinel.parentNode) {
sentinel.parentNode.removeChild(sentinel);
}
};
}, []);
return (
style={{
height: HEADER_HEIGHT,
backgroundColor: "lightgreen",
color: "#000000bd",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
Header
style={{
height: BREADCRUMBS_HEIGHT,
backgroundColor: "lightpink",
color: "#000000bd",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
Navbar
ref={stickyRef}
style={{
backgroundColor: "lightgray",
height: isStuck ? 60 : 300,
position: "sticky",
top: 0,
transition: "height 0.3s ease",
color: "#000000bd",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
Sticky
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ratione
ducimus nam a id ipsam, eum nihil minus ab dolorem exercitationem,
praesentium tempora pariatur ullam? Asperiores optio eos consequuntur
temporibus omnis, incidunt quia aspernatur autem mollitia. Alias
distinctio minima, quos repellat ipsa nesciunt quisquam amet cupiditate
perspiciatis sit optio reprehenderit esse, porro explicabo. Fuga iure,
iste doloribus corrupti pariatur accusamus, quia aspernatur quibusdam
facilis deserunt qui debitis accusantium consequuntur! Iusto repellendus
rem sint voluptatibus ipsam itaque deleniti mollitia repellat ratione
recusandae! Veritatis placeat soluta odio nihil, aliquid dolor iste
dolorem facilis laudantium id tempora nostrum, ducimus possimus
recusandae dicta porro enim sed sapiente explicabo incidunt repudiandae
modi. Distinctio explicabo id, repudiandae saepe totam eligendi facere
cum repellat voluptates aliquid adipisci quod ipsam ipsa dicta expedita
dolor non aperiam accusamus consequuntur, maiores dolores fugit? Nam
earum sapiente debitis! Odio exercitationem placeat iusto, nihil magnam,
accusamus itaque nam amet culpa distinctio aliquam quis expedita
suscipit eligendi temporibus ea aut veniam quia, ab eum labore corrupti
cupiditate ipsa!
);
}
export default App;
< /code>
В приведенном выше коде я хочу свернуть липкий раздел, когда он придерживается верхней части видового тома. Для этого я использовал API Browser Browser IncescectionObserver. Затем, если вы прокрутите вниз, вы увидите множественные обрушения и расширение липкой секции! Это работает, но мне не нравится это решение.
Я хочу чистое решение, которое не зависит от секции p Tag.>
Подробнее здесь: https://stackoverflow.com/questions/797 ... repeatedly
import { useEffect, useRef, useState } from "react";
const HEADER_HEIGHT = 64;
const BREADCRUMBS_HEIGHT = 61;
const OFFSET = 0;
function App() {
const stickyRef = useRef(null);
const [isStuck, setIsStuck] = useState(false);
useEffect(() => {
const stickyElement = stickyRef.current as unknown as HTMLDivElement;
if (!stickyElement) return;
const sentinel = document.createElement("div");
sentinel.style.height = "1px";
sentinel.style.position = "absolute";
sentinel.style.top = `${HEADER_HEIGHT + BREADCRUMBS_HEIGHT - OFFSET}px`;
sentinel.style.left = "0";
sentinel.style.right = "0";
sentinel.style.pointerEvents = "none";
sentinel.style.backgroundColor = "red";
sentinel.style.border = "1px dashed red";
sentinel.style.zIndex = "1";
stickyElement.parentNode?.insertBefore(sentinel, stickyElement);
const observer = new IntersectionObserver(
([entry]) => {
setIsStuck(!entry.isIntersecting);
},
{
root: null,
rootMargin: "0px",
threshold: 0,
}
);
observer.observe(sentinel);
return () => {
observer.disconnect();
if (sentinel.parentNode) {
sentinel.parentNode.removeChild(sentinel);
}
};
}, []);
return (
style={{
height: HEADER_HEIGHT,
backgroundColor: "lightgreen",
color: "#000000bd",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
Header
style={{
height: BREADCRUMBS_HEIGHT,
backgroundColor: "lightpink",
color: "#000000bd",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
Navbar
ref={stickyRef}
style={{
backgroundColor: "lightgray",
height: isStuck ? 60 : 300,
position: "sticky",
top: 0,
transition: "height 0.3s ease",
color: "#000000bd",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
Sticky
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ratione
ducimus nam a id ipsam, eum nihil minus ab dolorem exercitationem,
praesentium tempora pariatur ullam? Asperiores optio eos consequuntur
temporibus omnis, incidunt quia aspernatur autem mollitia. Alias
distinctio minima, quos repellat ipsa nesciunt quisquam amet cupiditate
perspiciatis sit optio reprehenderit esse, porro explicabo. Fuga iure,
iste doloribus corrupti pariatur accusamus, quia aspernatur quibusdam
facilis deserunt qui debitis accusantium consequuntur! Iusto repellendus
rem sint voluptatibus ipsam itaque deleniti mollitia repellat ratione
recusandae! Veritatis placeat soluta odio nihil, aliquid dolor iste
dolorem facilis laudantium id tempora nostrum, ducimus possimus
recusandae dicta porro enim sed sapiente explicabo incidunt repudiandae
modi. Distinctio explicabo id, repudiandae saepe totam eligendi facere
cum repellat voluptates aliquid adipisci quod ipsam ipsa dicta expedita
dolor non aperiam accusamus consequuntur, maiores dolores fugit? Nam
earum sapiente debitis! Odio exercitationem placeat iusto, nihil magnam,
accusamus itaque nam amet culpa distinctio aliquam quis expedita
suscipit eligendi temporibus ea aut veniam quia, ab eum labore corrupti
cupiditate ipsa!
);
}
export default App;
< /code>
В приведенном выше коде я хочу свернуть липкий раздел, когда он придерживается верхней части видового тома. Для этого я использовал API Browser Browser IncescectionObserver. Затем, если вы прокрутите вниз, вы увидите множественные обрушения и расширение липкой секции! Это работает, но мне не нравится это решение.
Я хочу чистое решение, которое не зависит от секции p Tag.>
Подробнее здесь: https://stackoverflow.com/questions/797 ... repeatedly
Мобильная версия