Méthode Cross-Browser pour déterminer le pourcentage de défilement Vertical en Javascript

Comment puis-je savoir quel pourcentage de la barre de défilement verticale un utilisateur a traversé à un moment donné?

Il est assez facile de piéger l'événement 'onscroll' à déclencher lorsque l'utilisateur fait défiler la page, mais comment puis-je savoir dans cet événement jusqu'où ils ont défilé? Dans ce cas, le pourcentage en particulier est ce qui est important. Je ne suis pas particulièrement inquiet d'une solution pour IE6.

Est-ce que l'un des principaux frameworks (Dojo, jQuery, Prototype, Mootools) expose cela dans un moyen simple compatible multi-navigateurs?

Santé,

30
demandé sur majelbstoat 2010-03-05 16:52:20

10 réponses

Octobre 2016: Fixe. Les parenthèses dans la démo jsbin étaient manquantes dans la réponse. Oups.

Chrome, Firefox, IE9+. démo en direct sur jsbin

var h = document.documentElement, 
    b = document.body,
    st = 'scrollTop',
    sh = 'scrollHeight';

var percent = (h[st]||b[st]) / ((h[sh]||b[sh]) - h.clientHeight) * 100;

Comme fonction:

function getScrollPercent() {
    var h = document.documentElement, 
        b = document.body,
        st = 'scrollTop',
        sh = 'scrollHeight';
    return (h[st]||b[st]) / ((h[sh]||b[sh]) - h.clientHeight) * 100;
}

Si vous préférez jQuery (réponse originale):

$(window).on('scroll', function(){
  var s = $(window).scrollTop(),
      d = $(document).height(),
      c = $(window).height();

  var scrollPercent = (s / (d - c)) * 100;
  
  console.clear();
  console.log(scrollPercent);
})
html{ height:100%; }
body{ height:300%; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
65
répondu Phil Ricketts 2017-09-13 08:48:52

Je pense avoir trouvé une bonne solution qui ne dépend d'aucune bibliothèque:

/**
 * Get current browser viewpane heigtht
 */
function _get_window_height() {
    return window.innerHeight || 
           document.documentElement.clientHeight ||
           document.body.clientHeight || 0;
}

/**
 * Get current absolute window scroll position
 */
function _get_window_Yscroll() {
    return window.pageYOffset || 
           document.body.scrollTop ||
           document.documentElement.scrollTop || 0;
}

/**
 * Get current absolute document height
 */
function _get_doc_height() {
    return Math.max(
        document.body.scrollHeight || 0, 
        document.documentElement.scrollHeight || 0,
        document.body.offsetHeight || 0, 
        document.documentElement.offsetHeight || 0,
        document.body.clientHeight || 0, 
        document.documentElement.clientHeight || 0
    );
}


/**
 * Get current vertical scroll percentage
 */
function _get_scroll_percentage() {
    return (
        (_get_window_Yscroll() + _get_window_height()) / _get_doc_height()
    ) * 100;
}
20
répondu Eduardo 2012-02-19 12:14:15

Cela devrait faire l'affaire, aucune bibliothèque requise:

function currentScrollPercentage()
{
    return ((document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight) * 100);
}
8
répondu Mark Bell 2010-03-05 14:22:09

Si vous utilisez Dojo, vous pouvez faire ce qui suit:

var vp = dijit.getViewport();
return (vp.t / (document.documentElement.scrollHeight - vp.h));

Qui retournera une valeur comprise entre 0 et 1.

2
répondu majelbstoat 2010-03-05 15:25:54

Cette question est là depuis longtemps, je sais, mais je suis tombé dessus en essayant de résoudre le même problème. Voici comment je l'ai résolu, dans jQuery:

D'abord, j'ai enveloppé la chose que je voulais faire défiler dans un div (pas sémantique, mais ça aide). Ensuite, réglez le débordement et la hauteur sur l'emballage.

<div class="content-wrapper" style="overflow: scroll; height:100px">
    <div class="content">Lot of content that scrolls</div>
</div>

Enfin, j'ai pu calculer le % scroll à partir de ces métriques:

var $w = $(this),
    scroll_top = $w.scrollTop(),
    total_height = $w.find(".content").height(),        
    viewable_area = $w.height(),
    scroll_percent = Math.floor((scroll_top + viewable_area) / total_height * 100);                

Voici un violon avec un exemple de travail: http://jsfiddle.net/prEGf/

2
répondu timemachine3030 2011-06-27 07:10:52

Ceux-ci ont parfaitement fonctionné pour moi dans Chrome 19.0, FF12, IE9:

function getElementScrollScale(domElement){
        return domElement.scrollTop / (domElement.scrollHeight - domElement.clientHeight);
    }

function setElementScrollScale(domElement,scale){
        domElement.scrollTop = (domElement.scrollHeight - domElement.clientHeight) * scale;
    }
2
répondu toske 2012-06-28 20:10:40
var maxScrollTop = messages.get(0).scrollHeight - messages.height();
var scroll = messages.scrollTop() / maxScrollTop; // [0..1]
0
répondu wishmaster35 2015-07-25 19:12:27

Attachez D'abord un écouteur d'événement à un document que vous souhaitez conserver

yourDocument.addEventListener("scroll", documentEventListener, false);

Puis:

function documentEventListener(){
  var currentDocument  = this;
  var docsWindow       = $(currentDocument.defaultView); // This is the window holding the document
  var docsWindowHeight = docsWindow.height(); // The viewport of the wrapper window
  var scrollTop        = $(currentDocument).scrollTop(); // How much we scrolled already, in the viewport
  var docHeight        = $(currentDocument).height();    // This is the full document height.

  var howMuchMoreWeCanScrollDown = docHeight - (docsWindowHeight + scrollTop);
  var percentViewed = 100.0 * (1 - howMuchMoreWeCanScrollDown / docHeight);
  console.log("More to scroll: "+howMuchMoreWeCanScrollDown+"pixels. Percent Viewed: "+percentViewed+"%");
}
0
répondu Nadav B 2017-06-02 12:19:22

Utiliser jQuery

$(window).scrollTop();

Vous obtiendrez la position de défilement, vous pouvez ensuite déterminer à partir de là quel est le pourcentage basé sur la hauteur de la fenêtre.

Il existe également une propriété DOM standard scrollTop que vous pouvez utiliser comme document.body.scrollTop mais je ne sais pas comment cela se comporte entre navigateurs, je suppose qu'il y a des incohérences alors la méthode jQuery en tient compte.

-1
répondu roryf 2010-03-05 13:56:18

J'ai trouvé un moyen de corriger une réponse précédente, donc cela fonctionne dans tous les cas. Testé sur Chrome, Firefox et Safari.

(((document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight) || 0) * 100)
-1
répondu Alexandru Rada 2015-11-19 13:56:39