简体   繁体   English

window.scrollTo 有回调吗?

[英]Is there a callback for window.scrollTo?

I want to call focus() on an input after the widow scrolled.我想在寡妇滚动后对输入调用focus() I'm using the smooth behavior for the scrollTo() method.我正在使用scrollTo()方法的平滑行为。 The problem is the focus method cut the smooth behavior.问题是focus方法切割了平滑的行为。 The solution is to call the focus function just after the scroll end.解决方案是在滚动结束后立即调用focus函数。

But I can't find any doc or threads speaking about how to detect the end of scrollTo method.但是我找不到任何关于如何检测scrollTo方法结束的文档或线程。

let el = document.getElementById('input')
let elScrollOffset = el.getBoundingClientRect().top
let scrollOffset = window.pageYOffset || document.documentElement.scrollTop
let padding = 12
window.scrollTo({
  top: elScrollOffset + scrollOffset - padding,
  behavior: 'smooth'
})
// wait for the end of scrolling and then
el.focus()

Any ideas?有任何想法吗?

I wrote a generic function based on the solution of George Abitbol, without overwriting window.onscroll:我根据George Abitbol的解决方案写了一个泛型函数,没有覆盖window.onscroll:

/**
 * Native scrollTo with callback
 * @param offset - offset to scroll to
 * @param callback - callback function
 */
function scrollTo(offset, callback) {
    const fixedOffset = offset.toFixed();
    const onScroll = function () {
            if (window.pageYOffset.toFixed() === fixedOffset) {
                window.removeEventListener('scroll', onScroll)
                callback()
            }
        }

    window.addEventListener('scroll', onScroll)
    onScroll()
    window.scrollTo({
        top: offset,
        behavior: 'smooth'
    })
}

I found a way to achieve what I want but I think it's a bit hacky, isn't it?我找到了一种方法来实现我想要的东西,但我认为它有点老套,不是吗?

let el = document.getElementById('input')
let elScrollOffset = el.getBoundingClientRect().top
let scrollOffset = window.pageYOffset || document.documentElement.scrollTop
let padding = 12
let target = elScrollOffset + scrollOffset - padding
window.scrollTo({
  top: target,
  behavior: 'smooth'
})
window.onscroll = e => {
  let currentScrollOffset = window.pageYOffset || document.documentElement.scrollTop
  // Scroll reach the target
  if (currentScrollOffset === target) {
    el.focus()
    window.onscroll = null // remove listener
  }
}

Other answers didn't fully work for me, therefore based on @Fabian von Ellerts answer, I wrote my own solution.其他答案并不完全适合我,因此基于@Fabian von Ellerts 的答案,我编写了自己的解决方案。

My problems were that :我的问题是:

  • The element I was scrolling (and all its parents along the hierarchy) always had a offsetTop of 0, so it was not working.我正在滚动的元素(及其沿层次结构的所有父元素)的offsetTop始终为 0,因此无法正常工作。

  • I needed to scroll a nested element.我需要滚动嵌套元素。

Using getBoundingClientRect and a container element as reference works :使用getBoundingClientRect和容器元素作为参考工作:

    const smoothScrollTo = (
        scrollContainer,
        scrolledContent,
        offset,
        callback
    ) => {
        const fixedOffset = (
            scrollContainer.getBoundingClientRect().top + offset
        ).toFixed()
        const onScroll = () => {
            if (
                scrolledContent.getBoundingClientRect().top.toFixed() ===
                fixedOffset
            ) {
                scrollContainer.removeEventListener('scroll', onScroll)
                callback()
            }
        }
        scrollContainer.addEventListener('scroll', onScroll)
        onScroll()
        scrollContainer.scrollTo({
            top: offset,
            behavior: 'smooth',
        })
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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