我必须平稳地scrollIntoView
某个特定元素,然后再做些事情。
示例
element.scrollIntoView({behavior: 'smooth'}).then(() => {
// Do something here
})
我知道无法以这种方式完成,因为本地scrollIntoView
不会返回Promise。但是,我如何实现这样的目标?
我正在使用Angular 7 BTW。因此,如果有任何指令可以帮助我实现这一目标,那就太好了。
答案 0 :(得分:3)
您可以使用原型,我认为这可以解决您的问题,而无需下载任何npm软件包
/* Extends Element Objects with a function named scrollIntoViewPromise
* options: the normal scrollIntoView options without any changes
*/
Element.prototype.scrollIntoViewPromise = function(options){
// "this" refers to the current element (el.scrollIntoViewPromise(options): this = el)
this.scrollIntoView(options);
// I create a variable that can be read inside the returned object ({ then: f() }) to expose the current element
let parent = this;
// I return an object with just a property inside called then
// then contains a function which accept a function as parameter that will be execute when the scroll ends
return {
then: function(x){
// Check out https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API for more informations
const intersectionObserver = new IntersectionObserver((entries) => {
let [entry] = entries;
// When the scroll ends (when our element is inside the screen)
if (entry.isIntersecting) {
// Execute the function into then parameter and stop observing the html element
setTimeout(() => {x(); intersectionObserver.unobserve(parent)}, 100)
}
});
// I start to observe the element where I scrolled
intersectionObserver.observe(parent);
}
};
}
element.scrollIntoViewPromise({behavior: "smooth"}).then(()=>console.log("EHI!"));
我已经创建了example。我知道这不是一个有角度的应用程序,但这是一个很好的起点。您只需要实现它即可(如果您使用的是Typescript,则必须创建一个使用新功能扩展Element的接口)。
答案 1 :(得分:1)
解决此问题的一种方法是使用smooth-scroll-into-view-if-nedded,它实际上会返回一个承诺,因此您可以绑定到它并应用您的逻辑。
答案 2 :(得分:1)
有一个想法,您可以如何捕捉动画结尾。 您可以在香草JS中使用“滚动”事件监听器进行操作。 检查此示例https://codepen.io/Floky87/pen/BEOYvN
var hiddenElement = document.getElementById("box");
var btn = document.querySelector(".btn");
var isScrolling;
function handleScroll(event) {
// Clear our timeout throughout the scroll
window.clearTimeout(isScrolling);
// Set a timeout to run after scrolling ends
isScrolling = setTimeout(function() {
alert(1);
document.removeEventListener("scroll", handleScroll);
}, 66);
}
function handleButtonClick() {
document.addEventListener("scroll", handleScroll, false);
hiddenElement.scrollIntoView({ block: "center", behavior: "smooth" });
}
btn.addEventListener("click", handleButtonClick);