Is there a callback for window.scrollTo?

前端 未结 3 1077
无人及你
无人及你 2020-12-15 16:32

I want to call focus() on an input after the widow scrolled. I\'m using the smooth behavior for the scrollTo() method. The problem is the foc

相关标签:
3条回答
  • 2020-12-15 17:08

    Other answers didn't fully work for me, therefore based on @Fabian von Ellerts answer, I wrote my own solution.

    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.

    • I needed to scroll a nested element.

    Using getBoundingClientRect and a container element as reference works :

        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',
            })
        }
    
    0 讨论(0)
  • 2020-12-15 17:18

    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
      }
    }
    
    0 讨论(0)
  • 2020-12-15 17:22

    I wrote a generic function based on the solution of George Abitbol, without overwriting window.onscroll:

    /**
     * Native scrollTo with callback
     * @param offset - offset to scroll to
     * @param callback - callback function
     */
    function scrollTo(offset, callback) {
        const fixedOffset = offset.toFixed(),
            onScroll = function () {
                if (window.pageYOffset.toFixed() === fixedOffset) {
                    window.removeEventListener('scroll', onScroll)
                    callback()
                }
            }
    
        window.addEventListener('scroll', onScroll)
        onScroll()
        window.scrollTo({
            top: offset,
            behavior: 'smooth'
        })
    }
    
    0 讨论(0)
提交回复
热议问题