简体   繁体   中英

Why intersection observer handler is not fired when using scrollTo or scrollIntoView?

An intersection observer is set up on an element. When the element is scrolled past a certain point, the intersection observer handler is fired as expected. However, if a button is clicked to scroll the element past that same point, the handler is not fired.

Why is that? Is there a way to force the handler to be fired when using scrollTo / scrollIntoView ?

 const container = document.getElementById("container"); const hello = document.getElementById("hello"); const button = document.getElementById("button"); const options = { rootMargin: "-100px 0px 0px 0px", threshold: 1 } const handleIntersect = entries => { entries.forEach((entry) => { console.log("handleIntersect") }); }; const observer = new IntersectionObserver(handleIntersect, options); observer.observe(hello); button.addEventListener("click", () => { container.scrollTo({ top: 120 }); })
 body { margin: 0; } #container { background-color: #ddd; height: 400px; overflow-y: auto; }.inner-container { height: 100px; border-bottom: 1px solid #bbb; position: absolute; top: 0; left: 0; right: 0; text-align: right; } #button { margin: 40px; font-size: 20px; } #hello { display: inline-block; padding: 20px 40px; background-color: blue; color: white; margin-top: 150px; margin-bottom: 500px; }
 <div id="container"> <div class="inner-container"> <button id="button">Scroll</button> </div> <div id="hello">Hello</div> </div>

you should add isIntersecting check

if(entry.isIntersecting){
console.log("hello")
}

I don't know if this solves your problem, But What I think is when we have scrollIntoView linked to a button we specify a value to the position of scrollbar if the button is clicked, for example when we click a button which has a scrollTo() function we expect the scrollbar to be at a specific place but that doesn't mean the scrollbar is sliding to the place which looks similar to the action that happens when we scroll the mouse.

In other words the intersection API fires an even when you cross a particular position or a point, however it does not fire an even if you just skip crossing the point and jump directly the desired position which happens when you use scrollIntoView,

In case you wonder that when you use scrollTo() to smooth scroll the webpage, you can visually see the scroll bar sliding to the particular point as if it passes the threshold point, however it is not the case, behind the scene the scrollbar just skip all the content and moves directly the specified position.

One way to counter the problem (not efficient) is to use looping, try looping from the current page offset value to your target value instead of hardcoding the value to the scrollIntoView(), it does gives you the desired output but the scrolling animation will be poor and it loses it's objective.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM