是否有window.scrollTo的回调?

时间:2018-09-12 10:05:46

标签: javascript

在寡妇滚动之后,我想在输入上调用focus()。我正在为scrollTo()方法使用平稳行为。问题是focus方法削减了平滑行为。解决方案是在滚动结束后立即调用focus函数。

但是我找不到任何有关如何检测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()

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

我找到了一种实现自己想要的方式的方法,但我认为这有点怪异,不是吗?

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
  }
}

答案 1 :(得分:0)

我基于George Abitbol的解决方案编写了一个通用函数,而没有覆盖window.onscroll:

/**
 * Native scrollTo with callback
 * @param offset - offset to scroll to
 * @param callback - callback function
 */
function scrollTo(offset, callback) {
    const onScroll = function () {
        const scrollTop = window.scrollTop || window.pageYOffset

        if (scrollTop === offset) {
            window.removeEventListener('scroll', onScroll)
            callback()
        }
    }
    window.addEventListener('scroll', onScroll)
    onScroll()
    window.scrollTo({
        top: offset,
        behavior: 'smooth'
    })
}

答案 2 :(得分:0)

其他答案对我而言并不完全有效,因此基于@Fabian von Ellerts的答案,我编写了自己的解决方案。

我的问题是:

  • 我正在滚动的元素(及其整个层次结构中的所有父元素)的offsetTop始终为0,因此无法正常工作。

  • 我需要滚动一个嵌套元素。

使用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',
        })
    }