我有一个页面,其中一个滚动条包含从数据库动态生成的带有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个像素太高了。 有人知道怎么解决吗?


当前回答

这适用于我的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;

其他回答

用绝对法定位锚

另一种方法是将锚定位在页面上想要的位置,而不是依赖于按偏移量滚动。我发现它可以更好地控制每个元素(例如。如果你想对某些元素有不同的偏移量),并且可能对浏览器API的变化/差异更有抵抗力。

<div id="title-element" style="position: relative;">
  <div id="anchor-name" style="position: absolute; top: -100px; left: 0"></div>
</div>

现在相对于元素的偏移量被指定为-100px。创建一个函数来创建这个锚,以便代码重用,或者如果你正在使用一个现代的JS框架,比如React,通过创建一个渲染锚的组件来实现,并传入锚的名称和每个元素的对齐方式,这些元素可能相同,也可能不相同。

然后使用:

const element = document.getElementById('anchor-name')
element.scrollIntoView({ behavior: 'smooth', block: 'start' });

平滑滚动,偏移量为100px。

这是我的两分钱。

我也有scrollIntoView滚动过去元素一点的问题,所以我创建了一个脚本(本机javascript),将一个元素前置到目的地,将它定位到顶部的css和滚动到那一个。滚动后,再次删除创建的元素。

HTML:

//anchor tag that appears multiple times on the page
<a href="#" class="anchors__link js-anchor" data-target="schedule">
    <div class="anchors__text">
        Scroll to the schedule
    </div>
</a>

//The node we want to scroll to, somewhere on the page
<div id="schedule">
    //html
</div>

Javascript文件:

(() => {
    'use strict';

    const anchors = document.querySelectorAll('.js-anchor');

    //if there are no anchors found, don't run the script
    if (!anchors || anchors.length <= 0) return;

    anchors.forEach(anchor => {
        //get the target from the data attribute
        const target = anchor.dataset.target;

        //search for the destination element to scroll to
        const destination = document.querySelector(`#${target}`);
        //if the destination element does not exist, don't run the rest of the code
        if (!destination) return;

        anchor.addEventListener('click', (e) => {
            e.preventDefault();
            //create a new element and add the `anchors__generated` class to it
            const generatedAnchor = document.createElement('div');
            generatedAnchor.classList.add('anchors__generated');

            //get the first child of the destination element, insert the generated element before it. (so the scrollIntoView function scrolls to the top of the element instead of the bottom)
            const firstChild = destination.firstChild;
            destination.insertBefore(generatedAnchor, firstChild);

            //finally fire the scrollIntoView function and make it animate "smoothly"
            generatedAnchor.scrollIntoView({
                behavior: "smooth",
                block: "start",
                inline: "start"
            });

            //remove the generated element after 1ms. We need the timeout so the scrollIntoView function has something to scroll to.
            setTimeout(() => {
                destination.removeChild(generatedAnchor);
            }, 1);
        })
    })
})();

CSS:

.anchors__generated {
    position: relative;
    top: -100px;
}

希望这能帮助到大家!

这适用于我的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;

一种解决方案是创建一个相对于目标具有偏移量的不可见临时元素,滚动到它,然后删除它。这也许不是最理想的,但在我工作的环境中,其他解决方案对我不起作用。例如:

const createOffsetElement = (element) => {
    const offsetElement = document.createElement('div');
    offsetElement.style = `
        position: relative;
        top: -10em;
        height: 1px;
        width: 1px;
        visibility: hidden;
    `;
    const inputWrapper = element.closest('.ancestor-element-class');
    inputWrapper.appendChild(offsetElement);
    return offsetElement;
};

const scrollTo = (element) => {
    const offsetElement = createOffsetElement(element);
    offsetElement.scrollIntoView({
        behavior: 'smooth',
    });
    offsetElement.remove();
};

我有这个,它对我非常有效:

// add a smooth scroll to element
scroll(el) {
el.scrollIntoView({
  behavior: 'smooth',
  block: 'start'});

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

希望能有所帮助。