web-dev-qa-db-fra.com

Vérifier si l'élément HTML a des barres de défilement

Quel est le moyen le plus rapide de vérifier si un élément a des barres de défilement?

Une chose est bien sûr de vérifier si l'élément est plus grand que sa fenêtre d'affichage, ce qui peut facilement être fait en vérifiant ces deux valeurs:

el.scrollHeight > el.offsetHeight || el.scrollWidth > el.offsetWidth

mais cela ne signifie pas pour autant qu'il comporte des barres de défilement (il peut donc être défilé par des humains).

Question

Comment vérifier les barres de défilement dans un navigateur multi 1 et 2 javascript seulement (comme dans pas de jQuery)?

Javascript seulement, parce que j'ai besoin de la plus petite charge possible, parce que j'aimerais écrire un filtre de sélection très rapide jQuery

// check for specific scrollbars
$(":scrollable(x/y/both)")

// check for ANY scrollbar
$(":scrollable")

Je suppose que je devrais vérifier les paramètres de style overflow, mais comment puis-je le faire en mode navigateur?

Modification supplémentaire

Pas seulement overflow paramètres de style. Vérifier si un élément a une barre de défilement n'est pas aussi simple qu'il y paraît. La première formule que j'ai écrite ci-dessus fonctionne bien lorsque l'élément n'a pas de bordure, mais lorsqu'il en a une (surtout lorsque la largeur d'une bordure est considérable), la dimension offset peut être supérieure à celle de scroll dimension mais l’élément peut toujours faire défiler. Nous devons en fait soustraire les bordures de la dimension offset pour obtenir la fenêtre de défilement réelle de l'élément et la comparer à la dimension scroll.

Pour référence future

:scrollable Le filtre de sélecteur jQuery est inclus dans mon plugin .scrollintoview() _ jQuery. Le code complet peut être trouvé dans mon article de blog si quelqu'un en a besoin. Même s'il ne fournissait pas la solution réelle, le code de Soumya m'a considérablement aidé à résoudre le problème. Cela m'a orienté dans la bonne direction.

97
Robert Koritnik

J'ai trouvé cela quelque part il y a quelques semaines. Cela a fonctionné pour moi.

var div = document.getElementById('container_div_id');

var hasHorizontalScrollbar = div.scrollWidth > div.clientWidth;
var hasVerticalScrollbar = div.scrollHeight > div.clientHeight;

/* you'll get true/false */
93
jzhinga

Essayer:

Pour barre de défilement verticale

el.scrollHeight> el.clientHeight

Pour barre de défilement horizontale

el.scrollWidth> el.clientWidth

Je sais que cela fonctionne pour IE8 et Firefox 3.6+ au moins.

16
Gary

Voici encore une autre solution:

Comme quelques personnes l'ont fait remarquer, comparer simplement offsetHeight et scrollHeight n'est pas suffisant, car ils diffèrent par les éléments à dépassement de capacité masqué, etc., qui n'ont toujours pas de barres de défilement. Donc, ici, je vérifie également si le débordement est scroll ou auto sur les styles calculés pour l'élément:

var isScrollable = function(node) {
  var overflowY = window.getComputedStyle(node)['overflow-y'];
  var overflowX = window.getComputedStyle(node)['overflow-x'];
  return {
    vertical: (overflowY === 'scroll' || overflowY === 'auto') && node.scrollHeight > node.clientHeight,
    horizontal: (overflowX === 'scroll' || overflowX === 'auto') && node.scrollWidth > node.clientWidth,
  };
}
14
lotif

Cela peut sembler (ou être un peu hackish, mais vous pouvez tester les propriétés scrollTop et scrollLeft.

S'ils sont supérieurs à 0, vous savez qu'il y a des barres de défilement. S'ils sont 0, définissez-les sur 1 et testez-les à nouveau pour voir si vous obtenez un résultat de 1. Puis définissez-les sur 0.

Exemple: http://jsfiddle.net/MxpR6/1/

function hasScroll(el, direction) {
    direction = (direction === 'vertical') ? 'scrollTop' : 'scrollLeft';
    var result = !! el[direction];

    if (!result) {
        el[direction] = 1;
        result = !!el[direction];
        el[direction] = 0;
    }
    return result;
}

alert('vertical? ' + hasScroll(document.body, 'vertical'));
alert('horizontal? ' + hasScroll(document.body, 'horizontal'));

Je pense qu'il y a une propriété différente pour IE, donc je mettrai à jour dans une minute avec cela.

EDIT: Apparaît comme si IE peut prendre en charge cette propriété. (Je ne peux pas tester IE maintenant.)

http://msdn.Microsoft.com/en-us/library/ms534618 (VS.85) .aspx

14
user113716

Je suis peut-être un peu en retard à la fête, mais ...

Je crois que vous pouvez détecter des barres de défilement avec e.offsetWidth vs e.clientWidth. La largeur de décalage comprend les bordures et les barres de défilement, le remplissage et la largeur. La largeur du client inclut le rembourrage et la largeur. S'il te plait regarde:

https://developer.mozilla.org/en/DOM/element.offsetWidth (deuxième image) https://developer.mozilla.org/en/DOM/element.clientWidth (deuxième image)

Vous devez vérifier:

  1. Débordement défini ou non sur l'élément pour auto/scroll (y compris overflowX/Y) à l'aide du style calculé/en cascade/actuel.
  2. Si le dépassement de capacité de l'élément est défini sur auto/scroll. Établissez offsetWidth et clientWidth.
  3. Si la largeur clientWidth est inférieure à la bordure droite offsetWidth (retrouvée dans le style calculé/en cascade/actuel), vous savez que vous avez une barre de défilement.

Faites la même chose pour la verticale (offset/clientHeight).

IE7 signale un clientHeight égal à 0 pour certains éléments (je n'ai pas vérifié pourquoi), vous devez donc toujours effectuer le premier contrôle de débordement.

J'espère que cela t'aides!

6
user140628

Il existe plusieurs problèmes en cas de vérification de l’existence de barres de défilement. L’un d’eux est que dans mac, vous n’avez pas de barre de défilement visible, de sorte que les deux solutions ci-dessus ne vous donneraient pas une réponse précise.

Ainsi, le rendu du navigateur n'étant pas très fréquent, vous pouvez vérifier le défilement après avoir modifié le défilement, puis le réinitialisé:

const hasScrollBar = (element) => {
  const {scrollTop} = element;

  if(scrollTop > 0) {
    return true;
  }

  element.scrollTop += 10;

  if(scrollTop === element.scrollTop) {
    return false;
  }

  // undoing the change
  element.scrollTop = scrollTop;
  return true;
};
2
hakobpogh

Juste déconner ici car aucune des solutions ci-dessus n’a fonctionné pour moi (jusqu’à présent). J'ai réussi à comparer le scrollheight d'une div à son offsetHeight.

var oh = $('#wrapDiv').get(0).offsetHeight;
var sh = $('#wrapDiv').get(0).scrollHeight;

Il semble me donner une comparaison précise ... jusqu'à présent. Est-ce que quelqu'un sait si c'est légitime?

1
Michael

Pour IE11 (Internet Explorer 11), je devais modifier la logique en:

// Subtract 3 (a small arbitrary number) to allow for IE reporting a difference of 1 when no scrollbar is present
var hasVerticalScrollbar = div.scrollHeight - 3 > div.clientHeight;

En effet, IE indique que scrollHeight est 1 supérieur à clientHeight lorsqu'aucune barre de défilement n'est présente, mais environ 9 plus grande lorsqu'une barre de défilement est présente.

0
danday74