ScrollIntoView()导致整个页面移动

imh*_*ere 80 javascript css

我正在使用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>
Run Code Online (Sandbox Code Playgroud)

listOfDivs来自ajax调用.使用移动野生动物园.

感谢您的帮助!

Bri*_*and 98

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

var target = document.getElementById("target");
target.parentNode.scrollTop = target.offsetTop;
Run Code Online (Sandbox Code Playgroud)

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

如果要滚动多个可滚动元素,则需要scrollTop根据offsetTop插入元素的s 单独更改每个元素.这应该给你细粒度的控制,以避免你遇到的问题.

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

target.parentNode.scrollTop = target.offsetTop - target.parentNode.offsetTop;
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,这仅在父级位于页面顶部时有效。你可能应该让它`target.parentNode.scrollTop = target.offsetTop - target.parentNode.offsetTop` (7认同)
  • offsetTop 是相对于最近定位的父节点,所以如果父节点有 `position: relative`,那么你不应该减去它的偏移量。但在大多数情况下你是对的。 (2认同)
  • 这是一个js小提琴:http://jsfiddle.net/LEqjm/258/,它还显示了ScrollIntoView不正确的行为. (2认同)

jfr*_*ohn 65

修复它:

element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' })
Run Code Online (Sandbox Code Playgroud)

请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

  • “block: 'nearest'” 有效,但“block: 'center'” (更好一点)仍然滚动视口。很高兴知道这是一个错误还是一个功能...... (13认同)
  • “最近”是什么意思?编辑:在这里找到答案:/sf/answers/3404502601/ (6认同)
  • @som我遇到了类似的问题,在使用“scrollIntoView()”后我的整个页面发生了偏移,最终阻止我出现这种情况的是主元素上的“overflow:clip;”。非常感谢! (4认同)
  • 这解决了我的问题。我在我们的网络应用程序中看到这种情况发生已经有一段时间了,但很难锁定它的重现。添加新功能后,每次都会发生这种情况,我能够将其追溯到此调用,该调用缺少 `block : 'nearest'` 参数。 (2认同)
  • 适用于 Chrome,但不适用于 Edge。 (2认同)
  • 我可以使用 `{ block: 'nearest', inline: 'center' }` 解决这个问题,方法是将 `overflow: Clip` 应用于过度滚动的父元素(在我的例子中是水平过度滚动) (2认同)

pad*_*otk 15

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

我的修复最终是:

  • 对于 Chrome:更改.scrollIntoView().scrollIntoView({block: 'nearest'})(感谢 @jfrohn)。
  • 对于 Firefox:应用于overflow: -moz-hidden-unscrollable;移动的容器元素。
  • 未在其他浏览器中测试。

  • 看起来“overflow:clip”是新的“-moz-hidden-unscrollable” (5认同)

小智 9

只是根据我在 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]
                    });
     }
Run Code Online (Sandbox Code Playgroud)

main_app_class是根类

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

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

  • “边界”不包含在 scollIntoView 规范中。有任何想法吗? (4认同)

小智 8

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


Yas*_*ash 8

添加更多信息以@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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Gui*_*eek 8

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

使用最近的解决。

const element = this.element.nativeElement;
const table = element.querySelector('.table-container');
table.scrollIntoView({
  behavior: 'smooth', block: 'nearest'
});
Run Code Online (Sandbox Code Playgroud)


Rob*_*nik 7

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

而不是默认的DOM实现,您可以使用动画动画的插件,没有任何不需要的效果.以下是使用默认值的最简单方法:

$("yourTargetLiSelector").scrollintoview();
Run Code Online (Sandbox Code Playgroud)

无论如何,请访问此博客文章,您可以阅读所有详细信息,最终将获得插件的GitHub源代码.

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

  • @Brilliand:这当然是正确的,但这并不意味着他们没有使用它或者不愿意使用它.我正在做的就是提供另一种选择.OP决定这是否是他们采取的路径.也许他们从未考虑过首先使用jQuery. (19认同)

Mic*_*dok 7

我添加了一种方法来显示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);
}
});
Run Code Online (Sandbox Code Playgroud)

  • 不是一个jQuery问题. (4认同)

dip*_*ent 7

var el = document.querySelector("yourElement");
window.scroll({top: el.offsetTop, behavior: 'smooth'});
Run Code Online (Sandbox Code Playgroud)