scrollIntoView Scrolls just too far

前端 未结 21 1916
盖世英雄少女心
盖世英雄少女心 2020-12-07 10:08

I have a page where a scroll bar containing table rows with divs in them is dynamically generated from the database. Each table row acts like a link, sort of like you\'d see

相关标签:
21条回答
  • 2020-12-07 10:56

    Smoothly scroll to a proper position

    Get correct y coordinate and use window.scrollTo({top: y, behavior: 'smooth'})

    const id = 'profilePhoto';
    const yOffset = -10; 
    const element = document.getElementById(id);
    const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset;
    
    window.scrollTo({top: y, behavior: 'smooth'});
    
    0 讨论(0)
  • 2020-12-07 10:57

    Based on the answer of Arseniy-II: I had the Use-Case where the scrolling entity was not window itself but a inner Template (in this case a div). In this scenario we need to set an ID for the scrolling container and get it via getElementById to use its scrolling function:

    <div class="scroll-container" id="app-content">
      ...
    </div>
    
    const yOffsetForScroll = -100
    const y = document.getElementById(this.idToScroll).getBoundingClientRect().top;
    const main = document.getElementById('app-content');
    main.scrollTo({
        top: y + main.scrollTop + yOffsetForScroll,
        behavior: 'smooth'
      });
    

    Leaving it here in case someone faces a similar situation!

    0 讨论(0)
  • 2020-12-07 10:58

    Assuming you want to scroll to the divs that are all at the same level in DOM and have class name "scroll-with-offset", then this CSS will solve the issue:

    .scroll-with-offset {    
      padding-top: 100px;
      margin-bottom: -100px;
    }
    

    The offset from the top of the page is 100px. It will only work as intended with block: 'start':

    element.scrollIntoView({ behavior: 'smooth', block: 'start' });
    

    What's happening is that the divs' top point is at the normal location but their inner contents start 100px below the normal location. That's what padding-top:100px is for. margin-bottom: -100px is to offset the below div's extra margin. To make the solution complete also add this CSS to offset the margins/paddings for the top-most and bottom-most divs:

    .top-div {
      padding-top: 0;
    }
    .bottom-div {
      margin-bottom: 0;
    }
    
    0 讨论(0)
  • 2020-12-07 11:02

    Another solution is to use "offsetTop", like this:

    var elementPosition = document.getElementById('id').offsetTop;
    
    window.scrollTo({
      top: elementPosition - 10, //add your necessary value
      behavior: "smooth"  //Smooth transition to roll
    });
    
    0 讨论(0)
  • 2020-12-07 11:03

    You can do it in two steps :

    el.scrollIntoView(true);
    window.scrollBy(0, -10); // Adjust scrolling with a negative value here
    
    0 讨论(0)
  • 2020-12-07 11:03

    Fix it in 20 seconds:

    This solution belongs to @Arseniy-II, I have just simplified it into a function.

    function _scrollTo(selector, yOffset = 0){
      const el = document.querySelector(selector);
      const y = el.getBoundingClientRect().top + window.pageYOffset + yOffset;
    
      window.scrollTo({top: y, behavior: 'smooth'});
    }
    

    Usage (you can open up the console right here in StackOverflow and test it out):

    _scrollTo('#question-header', 0);
    

    I'm currently using this in production and it is working just fine.

    0 讨论(0)
提交回复
热议问题