web-dev-qa-db-fra.com

Méthode multi-navigateurs pour déterminer le pourcentage de défilement vertical en Javascript

Comment savoir quel pourcentage de la barre de défilement verticale qu'un utilisateur a déplacée à 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'à quel point ils ont fait défiler? Dans ce cas, le pourcentage est particulièrement important. Je ne suis pas particulièrement inquiet pour une solution pour IE6.

Est-ce que l'un des principaux frameworks (Dojo, jQuery, Prototype, Mootools) l'expose d'une manière simple compatible avec plusieurs navigateurs?

À votre santé,

31
majelbstoat

Octobre 2016: corrigé. Les parenthèses dans la démo jsbin étaient absentes de la réponse. Oops.

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>

72
Phil Ricketts

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
Eduardo

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
Mark Bell

Je sais que cette question existe depuis longtemps, 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 emballé la chose que je voulais faire défiler dans une div (pas sémantique, mais ça aide). Puis définissez 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% de défilement à partir de ces mesures:

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 exemple avec lequel vous travaillez: http://jsfiddle.net/prEGf/

2
timemachine3030

Si vous utilisez Dojo, vous pouvez effectuer les opérations suivantes:

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

Ce qui retournera une valeur entre 0 et 1.

2
majelbstoat

Ceux-ci ont fonctionné pour moi parfaitement 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
toske
var maxScrollTop = messages.get(0).scrollHeight - messages.height();
var scroll = messages.scrollTop() / maxScrollTop; // [0..1]
0
wishmaster35

Commencez par attacher un écouteur d'événement à un document que vous souhaitez conserver.

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

Ensuite:

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
Nadav B