scrollIntoView Scrolls just too far

前端 未结 21 1914
盖世英雄少女心
盖世英雄少女心 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:42

    You can also use the element.scrollIntoView() options

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

    which most browsers support

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

    For an element in a table row, use JQuery to get the row above the one you want, and simply scroll to that row instead.

    Suppose I have multiple rows in a table, some of which should be reviewed by and admin. Each row requiring review has both and up and a down arrow to take you to the previous or next item for review.

    Here's a complete example that should just run if you make a new HTML document in notepad and save it. There's extra code to detect the top and bottom of our items for review so we don't throw any errors.

    <html>
    <head>
        <title>Scrolling Into View</title>
        <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
        <style>
            div.scroll { height: 6em; width: 20em; overflow: auto; }
            thead th   { position: sticky; top: -1px; background: #fff; }
            .up, .down { cursor: pointer; }
            .up:hover, .down:hover { color: blue; text-decoration:underline; }
        </style>
    </head>
    <body>
    <div class='scroll'>
    <table border='1'>
        <thead>
            <tr>
                <th>Review</th>
                <th>Data</th>
            </tr>
        </thead>
        <tbody>
            <tr id='row_1'>
                <th></th>
                <td>Row 1 (OK)</td>
            </tr>
            <tr id='row_2'>
                <th></th>
                <td>Row 2 (OK)</td>
            </tr>
            <tr id='row_3'>
                <th id='jump_1'><span class='up'>UP</span> <span class='down'>DN</span></th>
                <td>Row 3 (REVIEW)</td>
            </tr>
            <tr id='row_4'>
                <th></th>
                <td>Row 4 (OK)</td>
            </tr>
            <tr id='row_5'>
                <th id='jump_2'><span class='up'>UP</span> <span class='down'>DN</span></th>
                <td>Row 5 (REVIEW)</td>
            </tr>
            <tr id='row_6'>
                <th></th>
                <td>Row 6 (OK)</td>
            </tr>
            <tr id='row_7'>
                <th></th>
                <td>Row 7 (OK)</td>
            </tr>
            <tr id='row_8'>
                <th id='jump_3'><span class='up'>UP</span> <span class='down'>DN</span></th>
                <td>Row 8 (REVIEW)</td>
            </tr>
            <tr id='row_9'>
                <th></th>
                <td>Row 9 (OK)</td>
            </tr>
            <tr id='row_10'>
                <th></th>
                <td>Row 10 (OK)</td>
            </tr>
        </tbody>
    </table>
    </div>
    <script>
    $(document).ready( function() {
        $('.up').on('click', function() {
            var id = parseInt($(this).parent().attr('id').split('_')[1]);
            if (id>1) {
                var row_id = $('#jump_' + (id - 1)).parent().attr('id').split('_')[1];
                document.getElementById('row_' + (row_id-1)).scrollIntoView({behavior: 'smooth', block: 'start'});
            } else {
                alert('At first');
            }
        });
    
        $('.down').on('click', function() {
            var id = parseInt($(this).parent().attr('id').split('_')[1]);
            if ($('#jump_' + (id + 1)).length) {
                var row_id = $('#jump_' + (id + 1)).parent().attr('id').split('_')[1];
                document.getElementById('row_' + (row_id-1)).scrollIntoView({behavior: 'smooth', block: 'start'});
            } else {
                alert('At last');
            }
        });
    });
    </script>
    </body>
    </html>
    
    0 讨论(0)
  • 2020-12-07 10:48

    Building on an earlier answer, I am doing this in an Angular5 project.

    Started with:

    // el.scrollIntoView(true);
    el.scrollIntoView({
       behavior: 'smooth',
       block: 'start'
    });
    window.scrollBy(0, -10); 
    

    But this gave some problems and needed to setTimeout for the scrollBy() like this:

    //window.scrollBy(0,-10);
    setTimeout(() => {
      window.scrollBy(0,-10)
      }, 500);
    

    And it works perfectly in MSIE11 and Chrome 68+. I have not tested in FF. 500ms was the shortest delay I would venture. Going lower sometimes failed as the smooth scroll had not yet completed. Adjust as required for your own project.

    +1 to Fred727 for this simple but effective solution.

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

    Simple solution for scrolling specific element down

    const element = document.getElementById("element-with-scroll");
    element.scrollTop = element.scrollHeight - 10;
    
    0 讨论(0)
  • 2020-12-07 10:51

    If it's about 10px, then I guess you could simply manually adjust the containing div's scroll offset like that:

    el.scrollIntoView(true);
    document.getElementById("containingDiv").scrollTop -= 10;
    
    0 讨论(0)
  • 2020-12-07 10:52

    My main idea is creating a tempDiv above the view which we want to scroll to. It work well without lagging in my project.

    scrollToView = (element, offset) => {
        var rect = element.getBoundingClientRect();
        var targetY = rect.y + window.scrollY - offset;
    
        var tempDiv;
        tempDiv = document.getElementById("tempDiv");
        if (tempDiv) {
            tempDiv.style.top = targetY + "px";
        } else {
            tempDiv = document.createElement('div');
            tempDiv.id = "tempDiv";
            tempDiv.style.background = "#F00";
            tempDiv.style.width = "10px";
            tempDiv.style.height = "10px";
            tempDiv.style.position = "absolute";
            tempDiv.style.top = targetY + "px";
            document.body.appendChild(tempDiv);
        }
    
        tempDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
    

    Example using

    onContactUsClick = () => {
        this.scrollToView(document.getElementById("contact-us"), 48);
    }
    

    Hope it help

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