我有一个页面,其中一个滚动条包含从数据库动态生成的带有div的表行。每个表行就像一个链接,有点像你在视频播放器旁边看到的YouTube播放列表。

当用户访问页面时,他们所在的选项应该会转到滚动div的顶部。这个功能正在工作。问题是,这有点太过分了。比如他们的选项高了10像素。因此,页面被访问,url被用来识别选择了哪个选项,然后将该选项滚动到滚动div的顶部。注意:这不是窗口的滚动条,这是一个带有滚动条的div。

我正在使用这段代码,使它移动选中的选项到div的顶部:

var pathArray = window.location.pathname.split( '/' );

var el = document.getElementById(pathArray[5]);

el.scrollIntoView(true);

它将它移动到div的顶部,但大约10个像素太高了。 有人知道怎么解决吗?


当前回答

平滑滚动到适当的位置

这是大多数情况下更好的答案。它使用滚动边距和滚动填充CSS规则。 下面的解决方案使用getBoundingClientRect,它会触发一个额外的强制布局。

得到正确的y坐标并使用window。scrollTo({top: y,行为:'平滑'})

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'});

其他回答

根据arsenie - ii的回答:我有一个用例,其中滚动实体不是窗口本身,而是一个内部模板(在这种情况下是div)。在这个场景中,我们需要为滚动容器设置一个ID,并通过getElementById获取它来使用它的滚动函数:

<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'
  });

把它留在这里,以防有人面临类似的情况!

这适用于我的Chrome浏览器(平滑滚动,没有计时黑客)

它只是移动元素,开始滚动,然后再移动回来。

如果元素已经在屏幕上,则不会出现可见的“弹出”。

pos = targetEle.style.position;
top = targetEle.style.top;
targetEle.style.position = 'relative';
targetEle.style.top = '-20px';
targetEle.scrollIntoView({behavior: 'smooth', block: 'start'});
targetEle.style.top = top;
targetEle.style.position = pos;

基于之前的答案,我在一个Angular5项目中这样做。

开始:

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

但这样会产生一些问题,需要为scrollBy()设置timeout,如下所示:

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

它在MSIE11和Chrome 68+中工作完美。我没有在FF测试过。500毫秒是我敢说的最短延迟。向下走有时会失败,因为平滑的滚动还没有完成。根据您自己的项目进行调整。

+1到Fred727为这个简单而有效的解决方案。

对于表行中的元素,使用JQuery获取所需元素的上方行,然后简单地滚动到该行。

假设我在一个表中有多行,其中一些行应该由和admin检查。需要审查的每一行都有向上和向下的箭头,引导您到上一项或下一项进行审查。

这是一个完整的例子,如果你在记事本中创建一个新的HTML文档并保存它,它应该会运行。还有额外的代码来检测项目的顶部和底部以进行检查,这样我们就不会抛出任何错误。

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

也许这有点笨拙,但到目前为止还不错。我在angular 9工作。

文件.ts

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

. html文件

<button (click)="scroll(target)"></button>
<div  #target style="margin-top:-50px;padding-top: 50px;" ></div>

我用边距和填充顶部调整偏移量。

问候!