Javascript scrollIntoView () среднее выравнивание? - PullRequest
56 голосов
/ 19 января 2012

Javascript .scrollIntoView(boolean) обеспечивают только два варианта выравнивания.

  1. top
  2. bottom

Что если я хочу прокрутить вид таким образом.Я хочу, чтобы конкретный элемент был где-то посередине страницы?

Ответы [ 7 ]

55 голосов
/ 08 апреля 2016

Можно использовать 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/

Это решение более эффективно, чем переход по родительской цепочке, как в принятом ответе, иt включает загрязнение глобальной области видимости путем расширения прототипа ( обычно считается плохой практикой в ​​javascript ).

Метод getBoundingClientRect() поддерживается во всех современных браузерах.

39 голосов
/ 21 мая 2018

попробуйте это:

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

см. Дополнительную информацию и опции здесь: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

38 голосов
/ 19 января 2012

Используйте 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 );
6 голосов
/ 05 февраля 2017

Вы можете сделать это в два шага:

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);
3 голосов
/ 17 октября 2016

С 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 голосов
/ 28 августа 2018

Ни одно из решений на этой странице не работает, когда контейнер, кроме окна / документа, прокручивается.Подход 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);
}
2 голосов
/ 04 декабря 2017

Улучшение ответа @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
...