ScrollIntoView()导致整个页面移动

我正在使用ScrollIntoView()将列表中突出显示的项目滚动到视图中。
当我_向下滚动时,ABC_0运行良好。

但当我向上滚动时,ScrollIntoView(true)导致整个页面移动了一点,我认为这是有意的。

在使用ScrollIntoView(true)时,有没有一种方法可以避免整个页面移动?

这是我的页面的结构。

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

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

listOfDivs来自AJAX调用。使用Mobile Safari.

183835 次浏览

您可以使用scrollTop代替scrollIntoView()

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

JSFiddle:http://jsfiddle.net/LEqjm/

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

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

target.parentNode.scrollTop = target.offsetTop - target.parentNode.offsetTop;

jQuery插件scrollintoview()提高可用性

除了默认的DOM实现,你还可以使用一个插件,它可以动画移动,并且没有任何不必要的效果。下面是使用默认值的最简单方法:

$("yourTargetLiSelector").scrollintoview();

无论如何,转到这个博客文章,在那里你可以阅读所有的细节,并最终让你_插件的ABC_1。

此插件自动搜索最近的可滚动祖先元素并滚动它,以便所选元素位于其可见视口内。如果元素已经在视口中,它当然不会执行任何操作。

使用scrollIntoViewIfNeeded()..确保浏览器支持它。

我添加了一种方法来显示ScrollIntoViewhttp://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);
}
});

我有同样的问题,我解决了它通过删除transform:translateY CSS我把footer的页面。

使用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;
}
}
var el = document.querySelector("yourElement");
window.scroll({top: el.offsetTop, behavior: 'smooth'});

通过以下方式修复:

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

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

我也有这个问题,花了很多时间试图解决它。我希望我的决心还能帮助一些人。

我的解决方案最终是:

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

将更多信息添加到@Jesco后。

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

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

在我看来,他会把粘滞工具栏从屏幕上推开,或者在Fab按钮旁边输入“绝对”。

使用最接近的解决方案。

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

只是根据我最近的经验和在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

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

window.scroll({
top: document.getElementById('your-element')?.offsetParent.offsetTop,
behavior: 'smooth',
block: 'start',
})

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

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

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

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

并且选择越过我想要的那个中心。的选项(例如,在具有5行/可视选项的可滚动元素中,我选择了在我想要居中的选项之后的第2个选项,从而使所需元素居中。

enter image description here

我发现(在Chrome中),如果我从下向上滚动到我的元素,而不是从上向下滚动到我的元素,我可以更可靠地将元素滚动到父DIV的顶部(而不移动页面)。否则,虽然我的元素会滚动到视图中,但有时它仍然会低于DIV中所需的值。

为了实现这一点,我分两步滚动:

  1. myScrollableDiv.scrollTop = myScrollableDiv.scrollHeight,它会立即滚动到我的可滚动DIV的底部
  2. (根据此处的其他答案)将元素滚动到带有动画的视图中:
myElementWithinTheScrollingDiv.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
})