web-dev-qa-db-fra.com

Javascript scrollIntoView () alignement du milieu?

Javascript .scrollIntoView(boolean) fournit uniquement deux options d'alignement.

  1. haut
  2. bas

Que faire si je veux faire défiler la vue telle que. Je veux apporter un élément particulier quelque part au milieu de la page?

50
DHRUV BANSAL

Utilisez window.scrollTo() pour cela. Obtenez le haut de l'élément que vous souhaitez déplacer et soustrayez une moitié de la hauteur de la fenêtre.

Démo: 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 );
34
ThinkingStiff

Il est possible d’utiliser getBoundingClientRect() pour obtenir toutes les informations nécessaires à cette fin. Par exemple, vous pourriez faire quelque chose comme ceci:

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

Démo: http://jsfiddle.net/cxe73c22/

Cette solution est plus efficace que de remonter la chaîne parente, comme dans la réponse acceptée, et n'implique pas de polluer la portée mondiale en élargissant le prototype ( généralement considéré comme une mauvaise pratique en javascript ).

La méthode getBoundingClientRect() est supportée par tous les navigateurs modernes.

49
Rohan Orton

essaye ça : 

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

référez-vous ici pour plus d'informations et d'options: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

23
Sri7

Vous pouvez le faire en deux étapes:

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

Vous pouvez ajouter la hauteur de l'élément si vous voulez le centrer globalement, et non pas le haut:

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

Avec JQuery, j'utilise ceci:

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

}

Exemple:

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

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

Aucune des solutions de cette page ne fonctionne lorsqu'un conteneur autre que la fenêtre/le document est défilé. L'approche getBoundingClientRect échoue avec les éléments de positionnement absolus.

Dans ce cas, nous devons d'abord déterminer le parent à défilement et le faire défiler à la place de la fenêtre. Voici une solution qui fonctionne dans toutes les versions de navigateur actuelles et devrait même fonctionner avec IE8 et ses amis. L'astuce consiste à faire défiler l'élément vers le haut du conteneur afin de savoir exactement où il se trouve, puis soustraire la moitié de la hauteur de l'écran.

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

Améliorer la réponse de @Rohan Orton pour travailler avec le défilement vertical et horizontal.

La méthode Element.getBoundingClientRect () renvoie la taille d'un élément et sa position par rapport à la fenêtre d'affichage.

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

Utilisez Bitwise operator right shift pour obtenir la valeur int après la division.

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