ScrollIntoView()导致整个页面移动

时间:2012-06-14 19:18:56

标签: 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>

listOfDivs来自ajax调用。使用移动游猎。

提前感谢您的帮助!

13 个答案:

答案 0 :(得分:84)

您可以使用scrollTop代替scrollIntoView()

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

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

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

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

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

答案 1 :(得分:25)

修复:

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

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

答案 2 :(得分: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);
}
});

答案 3 :(得分:7)

使用scrollIntoViewIfNeeded()进行游戏...确保浏览器支持它。

答案 4 :(得分:7)

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

答案 5 :(得分:6)

jQuery插件scrollintoview()提高了可用性

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

$("yourTargetLiSelector").scrollintoview();

无论如何,请转到此blog post,您可以在其中阅读所有详细信息,最终将您转到该插件的GitHub source code

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

答案 6 :(得分:2)

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

我的修复最终是:

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

答案 7 :(得分:2)

在我看来,他会将粘性工具栏从屏幕上推开,或者在fab按钮旁边输入绝对值。

使用最近的求解。

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

答案 8 :(得分:1)

我遇到了同样的问题,我通过移除放置在页面transform:translateY上的footer CSS修复了此问题。

答案 9 :(得分:1)

使用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;
        }
    }

答案 10 :(得分:1)

@Jesco帖子中添加更多信息。

  • Element.scrollIntoViewIfNeeded() non-standard WebKit method(适用于Chrome,Opera和Safari浏览器)。
    如果该元素已经在浏览器窗口的可见区域内,则不会进行滚动
  • Element.scrollIntoView() 方法将调用该元素的元素滚动到浏览器窗口的可见区域。

mozilla.org scrollIntoView()链接中尝试以下代码。 发布以标识Browser

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

答案 11 :(得分:1)

只需根据我的最新经验并使用VueJ来添加答案即可。我发现下面的代码广告是最好的,无论如何也不会影响您的应用。

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

答案 12 :(得分:1)

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

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