122 votes

jQuery scroll () détecte quand l'utilisateur arrête de faire défiler

Ok avec ce..

$(window).scroll(function()
{
    $('.slides_layover').removeClass('showing_layover');
    $('#slides_effect').show();
});

Je peux dire quand quelqu'un est le défilement de ce que je comprends. Donc, avec ce que je suis en train d'essayer de comprendre comment les attraper quand quelqu'un s'est arrêté. À partir de l'exemple ci-dessus vous pouvez voir que je suis la suppression d'une classe à partir d'un ensemble d'éléments, tandis que le défilement est en cours. Cependant, je veux mettre cette classe de nouveau lorsque l'utilisateur cesse de défiler.

La raison pour cela est que je suis intention d'avoir une escale montrent que si la page est de défilement pour donner à la page un effet spécial, j'essaie de travailler sur. Mais de la seule classe que je suis en train de les supprimer lors du défilement des conflits avec cet effet comme un effet de transparence à la nature.

267voto

yckart Points 7517
$(window).scroll(function() {
    clearTimeout($.data(this, 'scrollTimer'));
    $.data(this, 'scrollTimer', setTimeout(function() {
        // do something
        console.log("Haven't scrolled in 250ms!");
    }, 250));
});

Mise à jour

J'ai écrit une extension pour améliorer jQuery par défaut de on-gestionnaire d'événements. Il attache une fonction de gestionnaire d'événement pour un ou plusieurs événements pour les éléments sélectionnés et les appels de la fonction de gestionnaire si l'événement n'a pas été déclenché pour un intervalle donné. Ceci est utile si vous voulez tirer un rappel seulement après un certain délai, comme l'événement de redimensionnement, ou tel.

Il est important de vérifier le github-pensions pour les mises à jour!

https://github.com/yckart/jquery.unevent.js

;(function ($) {
    var on = $.fn.on, timer;
    $.fn.on = function () {
        var args = Array.apply(null, arguments);
        var last = args[args.length - 1];

        if (isNaN(last) || (last === 1 && args.pop())) return on.apply(this, args);

        var delay = args.pop();
        var fn = args.pop();

        args.push(function () {
            var self = this, params = arguments;
            clearTimeout(timer);
            timer = setTimeout(function () {
                fn.apply(self, params);
            }, delay);
        });

        return on.apply(this, args);
    };
}(this.jQuery || this.Zepto));

L'utiliser comme n'importe quel autre on ou bind-gestionnaire d'événements, à l'exception que vous pouvez passer un paramètre supplémentaire, comme un dernier:

$(window).on('scroll', function(e) {
    console.log(e.type + '-event was 250ms not triggered');
}, 250);

http://yckart.github.com/jquery.unevent.js/

(cette démo utilise resize au lieu de scroll, mais qui s'en soucie?!)

54voto

Sinetheta Points 5357

jQuery debounce est un bon moyen de résoudre des problèmes comme celui-ci. jsFidlle

 $(window).scroll($.debounce( 250, true, function(){
    $('#scrollMsg').html('SCROLLING!');
}));
$(window).scroll($.debounce( 250, function(){
    $('#scrollMsg').html('DONE!');
}));
 

Le deuxième paramètre est le drapeau "at_begin". Ici, j'ai montré comment exécuter du code à la fois "scroll start" et "scroll finish".

10voto

chris Points 5381

Rob W suggected je vérifie sur un autre post ici sur la pile qui était essentiellement un poste similaire de mon original. Qui lecture à travers ce que j'ai trouvé un lien vers un site:

http://james.padolsey.com/javascript/special-scroll-events-for-jquery/

C'est en fait fini par résoudre mon problème, très bien après un peu de peaufinage pour mes propres besoins, mais sur tous les permis de faire beaucoup de la société hors de la voie et m'a sauvé environ 4 heures de train de comprendre sur mon propre.

Vu que ce post semble avoir un certain mérite, j'ai pensé que je pourrais revenir et de fournir le code trouvé à l'origine sur le lien mentionné, seulement dans le cas où l'auteur jamais décidé d'aller une direction différente avec le site et fini par prendre vers le bas le lien.

(function(){

    var special = jQuery.event.special,
        uid1 = 'D' + (+new Date()),
        uid2 = 'D' + (+new Date() + 1);

    special.scrollstart = {
        setup: function() {

            var timer,
                handler =  function(evt) {

                    var _self = this,
                        _args = arguments;

                    if (timer) {
                        clearTimeout(timer);
                    } else {
                        evt.type = 'scrollstart';
                        jQuery.event.handle.apply(_self, _args);
                    }

                    timer = setTimeout( function(){
                        timer = null;
                    }, special.scrollstop.latency);

                };

            jQuery(this).bind('scroll', handler).data(uid1, handler);

        },
        teardown: function(){
            jQuery(this).unbind( 'scroll', jQuery(this).data(uid1) );
        }
    };

    special.scrollstop = {
        latency: 300,
        setup: function() {

            var timer,
                    handler = function(evt) {

                    var _self = this,
                        _args = arguments;

                    if (timer) {
                        clearTimeout(timer);
                    }

                    timer = setTimeout( function(){

                        timer = null;
                        evt.type = 'scrollstop';
                        jQuery.event.handle.apply(_self, _args);

                    }, special.scrollstop.latency);

                };

            jQuery(this).bind('scroll', handler).data(uid2, handler);

        },
        teardown: function() {
            jQuery(this).unbind( 'scroll', jQuery(this).data(uid2) );
        }
    };

})();

5voto

Theo Points 550

J'admettais avec certains des commentaires ci-dessus qu'écouter pendant un délai n'était pas assez précis, car cela se déclencherait si vous arrêtez de déplacer la barre de défilement assez longtemps au lieu de cesser de faire défiler. Je pense qu'une meilleure solution est d'écouter l'utilisateur qui lâche la souris (mouseup) dès qu'il commence à faire défiler:

 $(window).scroll(function(){
    $('#scrollMsg').html('SCROLLING!');
    var stopListener = $(window).mouseup(function(){ // listen to mouse up
        $('#scrollMsg').html('STOPPED SCROLLING!');
        stopListner(); // Stop listening to mouse up after heard for the first time 
    });
});
 

et un exemple de ce travail peut être vu dans ce JSFiddle

3voto

justinbach Points 983

Vous pouvez définir un intervalle toutes les 500 ms environ, comme suit:

 var curOffset, oldOffset;
oldOffset = $(window).scrollTop();
var $el = $('.slides_layover'); // cache jquery ref
setInterval(function() {
  curOffset = $(window).scrollTop();
  if(curOffset != oldOffset) {
    // they're scrolling, remove your class here if it exists
    if($el.hasClass('showing_layover')) $el.removeClass('showing_layover');
  } else {
    // they've stopped, add the class if it doesn't exist
    if(!$el.hasClass('showing_layover')) $el.addClass('showing_layover');
  }
  oldOffset = curOffset;
}, 500);
 

Je n'ai pas testé ce code, mais le principe devrait fonctionner.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X