Scrolling to an Anchor using Transition/CSS3

前端 未结 10 908
-上瘾入骨i
-上瘾入骨i 2020-11-30 20:07

I have a series of links which are using an anchor mechanism:


      
10条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-30 20:52

    I implemented the answer suggested by @user18490 but ran into two problems:

    • First bouncing when user clicks on several tabs/links multiple times in short succession
    • Second, the undefined error mentioned by @krivar

    I developed the following class to get around the mentioned problems, and it works fine:

    export class SScroll{
        constructor(){
            this.delay=501      //ms
            this.duration=500   //ms
            this.lastClick=0
        }
    
        lastClick
        delay
        duration
    
        scrollTo=(destID)=>{
            /* To prevent "bounce" */
            /* https://stackoverflow.com/a/28610565/3405291 */
            if(this.lastClick>=(Date.now()-this.delay)){return}
            this.lastClick=Date.now()
    
            const dest=document.getElementById(destID)
            const to=dest.offsetTop
            if(document.body.scrollTop==to){return}
            const diff=to-document.body.scrollTop
            const scrollStep=Math.PI / (this.duration/10)
            let count=0
            let currPos
            const start=window.pageYOffset
            const scrollInterval=setInterval(()=>{
                if(document.body.scrollTop!=to){
                    count++
                    currPos=start+diff*(.5-.5*Math.cos(count*scrollStep))
                    document.body.scrollTop=currPos
                }else{clearInterval(scrollInterval)}
            },10)
        }
    }
    

    UPDATE

    There is a problem with Firefox as mentioned here. Therefore, to make it work on Firefox, I implemented the following code. It works fine on Chromium-based browsers and also Firefox.

    export class SScroll{
        constructor(){
            this.delay=501      //ms
            this.duration=500   //ms
            this.lastClick=0
        }
        lastClick
        delay
        duration
        scrollTo=(destID)=>{
            /* To prevent "bounce" */
            /* https://stackoverflow.com/a/28610565/3405291 */
            if(this.lastClick>=(Date.now()-this.delay)){return}
    
            this.lastClick=Date.now()
            const dest=document.getElementById(destID)
            const to=dest.offsetTop
            if((document.body.scrollTop || document.documentElement.scrollTop || 0)==to){return}
    
            const diff=to-(document.body.scrollTop || document.documentElement.scrollTop || 0)
            const scrollStep=Math.PI / (this.duration/10)
            let count=0
            let currPos
            const start=window.pageYOffset
            const scrollInterval=setInterval(()=>{
                if((document.body.scrollTop || document.documentElement.scrollTop || 0)!=to){
                    count++
                    currPos=start+diff*(.5-.5*Math.cos(count*scrollStep))
                    /* https://stackoverflow.com/q/28633221/3405291 */
                    /* To support both Chromium-based and Firefox */
                    document.body.scrollTop=currPos
                    document.documentElement.scrollTop=currPos
                }else{clearInterval(scrollInterval)}
            },10)
        }
    }
    

提交回复
热议问题