Javascript scrollIntoView()中间对齐?


76

Javascript.scrollIntoView(boolean)仅提供两个对齐选项。

  1. 最佳
  2. 底部

如果我想滚动视图怎么办。我想将特定元素带到页面中间吗?

Answers:


46

使用window.scrollTo()此。获取要移动到的元素的顶部,然后减去窗口高度的一半。

演示:http : //jsfiddle.net/ThinkingStiff/MJ69d/

Element.prototype.documentOffsetTop = function () {
    return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop() : 0 );
};

var top = document.getElementById( 'middle' ).documentOffsetTop() - ( window.innerHeight / 2 );
window.scrollTo( 0, top );

2
遍及

我喜欢offsetTop - (container / 2)。很简单,但是我没有想到。
user2954463 '10

85

试试这个 :

 document.getElementById('myID').scrollIntoView({
            behavior: 'auto',
            block: 'center',
            inline: 'center'
        });

请参阅此处以获取更多信息和选项:https : //developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView


9
与polyfill结合使用,这是最佳答案。npmjs.com/package/smoothscroll-polyfill
ryanrain '18

5
仅Chrome和Opera完全支持块和内联,甚至平滑滚动polyfill也不能。这是我们想要的解决方案,但不幸的是,这种解决方案无效。
dube

我在Ang11的IE11,Firefox,Chrome和Safari上的项目中使用的是相同的解决方案
。– hakuna

2
@ Sri7 Safari,IE和Edge无法理解的对象选项,无法scrollIntoView做任何他们想做的事情。即使是最新版本;我只是再次测试了。
dube

我可以确认,到目前为止,这不适用于移动式野生动物园。window.scrollBy有效。
Fabian von Ellerts

71

可以用来getBoundingClientRect()获取实现此目的所需的所有信息。例如,您可以执行以下操作:

const element = document.getElementById('middle');
const elementRect = element.getBoundingClientRect();
const absoluteElementTop = elementRect.top + window.pageYOffset;
const middle = absoluteElementTop - (window.innerHeight / 2);
window.scrollTo(0, middle);

演示:http//jsfiddle.net/cxe73c22/

这种解决方案比沿父链走更有效(如已接受的答案),并且不涉及通过扩展原型来污染全局范围(通常被认为是javascript中的不良做法)。

getBoundingClientRect()所有现代浏览器均支持该方法。


可悲的是,这与绝对定位的元素中断了。
dube

当元素位于可滚动容器而不是页面中时,是否可以编辑答案以包括如何做?我尝试过:jsfiddle.net/qwxvts4u/1
JBis


8

您可以分两个步骤进行操作:

myElement.scrollIntoView(true);
var viewportH = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
window.scrollBy(0, -viewportH/2); // Adjust scrolling with a negative value here

如果要全局居中而不是使其顶部居中,则可以添加元素的高度:

myElement.scrollIntoView(true);
var viewportH = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
window.scrollBy(0, (myElement.getBoundingClientRect().height-viewportH)/2);

2
这是2018年的最佳答案。首先使用正常的“ scrollIntoView”,因为Firefox 36至58中的“ ​​center”选项已损坏,并且IE不支持该选项,请参阅此developer.mozilla.org/en-US/docs / Web / API / Element /…。然后您可以通过计算视口的一半来将滚动条居中,然后将滚动条移到那里。
crisc82

3

通过JQuery,我可以使用以下代码:

function scrollToMiddle(id) {

    var elem_position = $(id).offset().top;
    var window_height = $(window).height();
    var y = elem_position - window_height/2;

    window.scrollTo(0,y);

}

例:

<div id="elemento1">Contenido</div>

<script>
    scrollToMiddle("#elemento1");
</script>


2

改善@Rohan Orton垂直和水平滚动工作的答案。

所述Element.getBoundingClientRect()方法返回的元素的相对于视其位置和大小。

var ele = $x("//a[.='Ask Question']");
console.log( ele );

scrollIntoView( ele[0] );

function scrollIntoView( element ) {
    var innerHeight_Half = (window.innerHeight >> 1); // Int value
                        // = (window.innerHeight / 2); // Float value
    console.log('innerHeight_Half : '+ innerHeight_Half);

    var elementRect = element.getBoundingClientRect();

    window.scrollBy( (elementRect.left >> 1), elementRect.top - innerHeight_Half);
}

除后使用Bitwise operator右移获取int值。

console.log( 25 / 2 ); // 12.5
console.log( 25 >> 1 ); // 12

2

当滚动窗口/文档以外的容器时,此页面上的解决方案均无效。的getBoundingClientRect方法对于绝对定位的元素失败。

在这种情况下,我们需要先确定可滚动的父级,然后滚动它而不是窗口。这是一个可以在所有当前浏览器版本中使用的解决方案,甚至可以与IE8和朋友一起使用。诀窍是将元素滚动到容器的顶部,以便我们确切地知道它在哪里,然后减去屏幕高度的一半。

function getScrollParent(element, includeHidden, documentObj) {
    let style = getComputedStyle(element);
    const excludeStaticParent = style.position === 'absolute';
    const overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;

    if (style.position === 'fixed') {
        return documentObj.body;
    }
    let parent = element.parentElement;
    while (parent) {
        style = getComputedStyle(parent);
        if (excludeStaticParent && style.position === 'static') {
            continue;
        }
        if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {
            return parent;
        }
        parent = parent.parentElement;
    }

    return documentObj.body;
}

function scrollIntoViewCentered(element, windowObj = window, documentObj = document) {
    const parentElement = getScrollParent(element, false, documentObj);
    const viewportHeight = windowObj.innerHeight || 0;

    element.scrollIntoView(true);
    parentElement.scrollTop = parentElement.scrollTop - viewportHeight / 2;

    // some browsers (like FireFox) sometimes bounce back after scrolling
    // re-apply before the user notices.
    window.setTimeout(() => {
        element.scrollIntoView(true);
        parentElement.scrollTop = parentElement.scrollTop - viewportHeight / 2;
    }, 0);
}


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.