173

我正在使用 ScrollIntoView() 将列表中突出显示的项目滚动到视图中。当我向下滚动时, ScrollIntoView(false) 工作得很好。但是当我向上滚动时, ScrollIntoView(true) 会导致整个页面移动一点,我认为这是有意的。使用 ScrollIntoView(true) 时有没有办法避免整个页面移动?

这是我页面的结构 -

#listOfDivs {
  position:fixed;
  top:100px;
  width: 300px;
  height: 300px;
  overflow-y: scroll;
}

<div="container">
    <div="content"> 
         <div id="listOfDivs"> 
             <div id="item1"> </div>
             <div id="item2"> </div>
             <div id="itemn"> </div>
         </div>
    </div>
</div>

listOfDivs 来自 ajax 调用。使用移动 Safari。

4

14 回答 14

238

修复它:

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

见:https ://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

于 2018-10-16T12:22:03.677 回答
158

您可以使用scrollTop而不是scrollIntoView()

var target = document.getElementById("target");
target.parentNode.scrollTop = target.offsetTop;

jsFiddle:http: //jsfiddle.net/LEqjm/

如果要滚动多个可滚动元素,则需要根据中间元素scrollTop的 s 单独更改每个元素的 。offsetTop这应该为您提供细粒度的控制,以避免您遇到的问题。

编辑: offsetTop 不一定相对于父元素 - 它是相对于第一个定位的祖先。如果父元素未定位(相对、绝对或固定),您可能需要将第二行更改为:

target.parentNode.scrollTop = target.offsetTop - target.parentNode.offsetTop;
于 2012-06-14T21:08:29.033 回答
19
var el = document.querySelector("yourElement");
window.scroll({top: el.offsetTop, behavior: 'smooth'});
于 2018-08-10T16:17:22.867 回答
16

我也遇到了这个问题,花了很多时间来解决它。我希望我的决议仍然可以帮助一些人。

我的修复最终是:

  • 对于 Chrome:更改.scrollIntoView().scrollIntoView({block: 'nearest'})(感谢 @jfrohn)。
  • 对于 Firefox:应用于overflow: -moz-hidden-unscrollable;发生变化的容器元素。
  • 未在其他浏览器中测试。
于 2018-12-07T09:47:16.383 回答
12

玩弄scrollIntoViewIfNeeded()...确保浏览器支持它。

于 2016-03-11T18:37:53.197 回答
10

在我的上下文中,他会将粘性工具栏从屏幕上推开,或者在绝对按钮旁边输入。

使用最近求解。

const element = this.element.nativeElement;
const table = element.querySelector('.table-container');
table.scrollIntoView({
  behavior: 'smooth', block: 'nearest'
});
于 2020-04-30T11:33:54.577 回答
8

我添加了一种方法来显示 ScrollIntoView 的不当行为 - http://jsfiddle.net/LEqjm/258/ [应该是评论,但我没有足够的声誉]

$("ul").click(function() {
    var target = document.getElementById("target");
if ($('#scrollTop').attr('checked')) {
    target.parentNode.scrollTop = target.offsetTop;    
} else {
        target.scrollIntoView(!0);
}
});
于 2016-09-01T12:40:09.537 回答
6

jQuery插件scrollintoview()增加了可用性

除了默认的 DOM 实现之外,您还可以使用动画移动并且没有任何不需要的效果的插件。这是使用默认值的最简单方法:

$("yourTargetLiSelector").scrollintoview();

无论如何,请访问此博客文章,您可以在其中阅读所有详细信息,并最终将您带到该插件的GitHub 源代码

该插件会自动搜索最近的可滚动祖先元素并滚动它,以便选定元素位于其可见视口内。如果元素已经在视口中,它当然不会做任何事情。

于 2012-06-15T07:02:50.787 回答
6

添加更多信息以@Jesco发布。

mozilla.org scrollIntoView()在链接中尝试以下代码。发布以识别浏览器

var xpath = '//*[@id="Notes"]';
ScrollToElement(xpath);

function ScrollToElement(xpath) {
    var ele = $x(xpath)[0];
    console.log( ele );

    var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);
    if (isChrome) { // Chrome
        ele.scrollIntoViewIfNeeded();
    } else {
        var inlineCenter = { behavior: 'smooth', block: 'center', inline: 'start' };
        ele.scrollIntoView(inlineCenter);
    }
}
于 2019-02-04T11:20:20.110 回答
3

使用 Brilliant 的想法,这是一个仅在元素当前不可见时才(垂直)滚动的解决方案。这个想法是获取视口的边界框和要在浏览器窗口坐标空间中显示的元素。检查它是否可见,如果不可见,则滚动所需的距离,以便元素显示在视口的顶部或底部。

    function ensure_visible(element_id)
    {
        // adjust these two to match your HTML hierarchy
        var element_to_show  = document.getElementById(element_id);
        var scrolling_parent = element_to_show.parentElement;

        var top = parseInt(scrolling_parent.getBoundingClientRect().top);
        var bot = parseInt(scrolling_parent.getBoundingClientRect().bottom);

        var now_top = parseInt(element_to_show.getBoundingClientRect().top);
        var now_bot = parseInt(element_to_show.getBoundingClientRect().bottom);

        // console.log("Element: "+now_top+";"+(now_bot)+" Viewport:"+top+";"+(bot) );

        var scroll_by = 0;
        if(now_top < top)
            scroll_by = -(top - now_top);
        else if(now_bot > bot)
            scroll_by = now_bot - bot;
        if(scroll_by != 0)
        {
            scrolling_parent.scrollTop += scroll_by; // tr.offsetTop;
        }
    }
于 2018-06-06T12:58:34.790 回答
3

只是根据我的最新经验和在 VueJs 上的工作添加一个答案。我发现下面的代码广告最好,无论如何它不会影响您的应用程序。

const el = this.$el.getElementsByClassName('your_element_class')[0];
if (el) {
   scrollIntoView(el,
                  {
                       block: 'nearest',
                       inline: 'start',
                       behavior: 'smooth',
                       boundary: document.getElementsByClassName('main_app_class')[0]
                    });
     }

main_app_class是根类

your_element_class是您可以滚动到的元素/视图

对于不支持 ScrollIntoView() 的浏览器,只需使用下面的库,它的真棒 https://www.npmjs.com/package/scroll-into-view-if-needed

于 2020-11-07T16:42:09.203 回答
1

我有同样的问题,我通过删除transform:translateY我放置在footer页面上的 CSS 来修复它。

于 2017-04-12T20:04:06.090 回答
1

ScrollIntoView() 导致页面移动。但是下面的代码对我来说很好,并将屏幕移动到元素的顶部:

window.scroll({
  top: document.getElementById('your-element')?.offsetParent.offsetTop,
  behavior: 'smooth',
  block: 'start',
})
于 2021-03-23T23:04:17.703 回答
1

FWIW:我发现(在 Chrome 95 和 Firefox 92(所有 Mac)中)使用:

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

在可滚动的选项列表上会稍微滚动一下 body 元素,所以我选择使用:

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

并选择一个超过我想要居中的选项(例如,在一个可滚动的元素中,可以查看 5 行/选项,我选择了第二个选项,超过了我想要居中的那个,从而使所需元素居中。

在此处输入图像描述

于 2021-11-01T17:51:11.387 回答