Обратный вызов на пересечении наблюдается неоднократно ⇐ CSS
-
Anonymous
Обратный вызов на пересечении наблюдается неоднократно
const {
useEffect,
useRef,
useState
} = 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;
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 ( <
>
<
div style = {
{
height: HEADER_HEIGHT,
backgroundColor: "lightgreen",
color: "#000000bd",
display: "flex",
alignItems: "center",
justifyContent: "center"
}
} >
Header <
/div> <
div style = {
{
height: BREADCRUMBS_HEIGHT,
backgroundColor: "lightpink",
color: "#000000bd",
display: "flex",
alignItems: "center",
justifyContent: "center"
}
} >
Navbar <
/div> <
div 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 <
/div> <
p style = {
{
margin: 0,
padding: 16
}
} >
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!
<
/p> < /
>
);
}
ReactDOM.createRoot(document.getElementById("root")).render( < App / > );< /code>
body {
margin: 0;
padding: 0;
}< /code>
< /code>
< /div>
< /div>
< /p>
const observer = new IntersectionObserver(
([entry]) => {
setIsStuck(!entry.isIntersecting);
}, {
root: null,
rootMargin: "0px",
threshold: 0
}
);
< /code>
Я хочу свернуть липкую секцию, когда он застрял в верхней части просмотра. Для этого я использовал API Browser Browser IncescectionObserver. Затем, если вы прокрутите вниз, вы увидите множественные обрушения и расширение липкой секции! Это работает, но мне не нравится это решение.
Я хочу чистое решение, которое не зависит от секции p Tag.>
Подробнее здесь: https://stackoverflow.com/questions/797 ... repeatedly
const {
useEffect,
useRef,
useState
} = 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;
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 ( <
>
<
div style = {
{
height: HEADER_HEIGHT,
backgroundColor: "lightgreen",
color: "#000000bd",
display: "flex",
alignItems: "center",
justifyContent: "center"
}
} >
Header <
/div> <
div style = {
{
height: BREADCRUMBS_HEIGHT,
backgroundColor: "lightpink",
color: "#000000bd",
display: "flex",
alignItems: "center",
justifyContent: "center"
}
} >
Navbar <
/div> <
div 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 <
/div> <
p style = {
{
margin: 0,
padding: 16
}
} >
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!
<
/p> < /
>
);
}
ReactDOM.createRoot(document.getElementById("root")).render( < App / > );< /code>
body {
margin: 0;
padding: 0;
}< /code>
< /code>
< /div>
< /div>
< /p>
const observer = new IntersectionObserver(
([entry]) => {
setIsStuck(!entry.isIntersecting);
}, {
root: null,
rootMargin: "0px",
threshold: 0
}
);
< /code>
Я хочу свернуть липкую секцию, когда он застрял в верхней части просмотра. Для этого я использовал API Browser Browser IncescectionObserver. Затем, если вы прокрутите вниз, вы увидите множественные обрушения и расширение липкой секции! Это работает, но мне не нравится это решение.
Я хочу чистое решение, которое не зависит от секции p Tag.>
Подробнее здесь: https://stackoverflow.com/questions/797 ... repeatedly
Мобильная версия