93 votes

Détecter si l'événement de défilement a été créé par l'utilisateur

Est-il possible de savoir si un événement de défilement a été déclenché par le navigateur ou par l'utilisateur? Plus précisément, lors de l'utilisation du bouton retour, un navigateur peut sauter à la dernière position de défilement connue. Si je lie un événement de défilement, comment puis-je savoir si cela a été causé par l'utilisateur ou par le navigateur?

$(document).scroll( function(){ 
    //qui a fait cela ?!
});

Je distingue trois types de situations qui provoquent un défilement dans un navigateur.

  1. L'utilisateur effectue une action. Par exemple, utilise la molette de la souris, les touches de direction, les touches de page haut/bas, les touches de début/fin, clique sur la barre de défilement ou en fait glisser le curseur.
  2. Le navigateur défile automatiquement. Par exemple, lorsque vous utilisez le bouton retour dans votre navigateur, il sautera automatiquement à la dernière position de défilement connue.
  3. Le JavaScript effectue un défilement. Par exemple, element.scrollTo(x,y).

1 votes

Je ne suis pas sûr de votre question, si vous considérez le saut en utilisant le bouton retour vers moi un événement de défilement du navigateur ou de l'utilisateur. En général : Que considérez-vous comme "défilement par le navigateur" ? Si vous voulez dire le défilement initié par votre script, alors tout ce que vous avez à faire, c'est lorsque votre script défile, soit de désactiver le gestionnaire d'événements, soit de définir un indicateur pour que le gestionnaire d'événements sache l'ignorer.

0 votes

J'ai considéré le défilement via le bouton de retour comme un "défilement du navigateur". Tout autre chose - la molette de la souris, les flèches haut/bas, le clic sur le bouton central, etc. serait un défilement de l'utilisateur. Je suppose que ma vraie question pourrait être - y a-t-il un moyen de différencier d'où provient un événement ? J'ai regardé les propriétés sur l'objet événement, mais je n'ai rien trouvé. Les trois scénarios que je peux imaginer sont le défilement initié par le navigateur, le défilement initié par JavaScript et le défilement initié par l'utilisateur. J'espère que cela clarifie les choses.

0 votes

@mrtsherman J'ai trouvé certains de ces éléments tout en obtenant le même résultat : stackoverflow.com/questions/2834667/…

2voto

Rusty Jeans Points 1292

Vous pouvez vérifier la position de défilement dès que la page est prête. Lorsque vous déclenchez l'événement de défilement, vérifiez que la position de défilement est différente de celle qu'elle était lorsque la page a été chargée. Enfin, assurez-vous de vider la valeur stockée une fois que la page a été défilée.

$(function () {
    var loadScrollTop = ($(document).scrollTop() > 0 ? $(document).scrollTop() : null);
    $(document).scroll(function (e) {
        if ( $(document).scrollTop() !== loadScrollTop) {
            // code de défilement ici!
        }
        loadScrollTop = null;
    });
});

0 votes

Merci pour cette idée. Il y a quelques scénarios que cela ne couvre pas tout à fait pour moi. Bien que ce soit une bonne idée et je la garderai dans ma poche arrière si jamais j'en ai besoin.

0 votes

Simple et dans la plupart des cas efficace.

1voto

Alex Kuzmin Points 44

Il existe une autre manière de séparer le défilement créé par l'utilisateur : vous pouvez utiliser les gestionnaires d'événements alternatifs, par exemple 'mousewheel', 'touchmove', 'keydown' avec les codes 38 et 40 pour le défilement avec les flèches, pour défilement avec la barre de défilement - si l'événement 'scroll' est déclenché simultanément avec 'mousedown' jusqu'à l'événement 'mouseup'.

0voto

Adriano Silva Points 584

Plus d'informations dans Javascript Tutorial - The Scroll Wheel

0voto

Firsh Points 187

En ce qui concerne :

Plus précisément, lorsque vous utilisez le bouton retour d'un navigateur, celui-ci peut sauter à la dernière position de défilement connue.

Cela se déclenche très rapidement, juste après le rendu de la page. Vous pouvez simplement retarder l'écoute de l'événement de défilement d'une seconde ou plus.

2 votes

Il ne s'agit pas d'une solution robuste. Le saut est dépendant du temps de chargement de la page. Le navigateur retarde le saut jusqu'à ce que la page soit complètement chargée. Cela empêche les éléments de la page qui chargent et modifient la hauteur de la page (comme les images) de défiler hors de la vue.

-1voto

nottombrown Points 356

Très utile. Voici une version coffeescript pour ceux qui le préfèrent.

$ ->
  S.userScroll = false

  # réinitialiser le drapeau sur retour/arrière
  if $.history?
    $.history.init (hash) ->
      S.userScroll = false

  mouseEvent = (e)->
    S.userScroll = true

  $(document).keydown (e) ->
    importantKey =  (e.which == 33 or        # page haut
      e.which == 34 or    # page bas
      e.which == 32 or    # espace
      e.which == 38 or    # haut
      e.which == 40 or    # bas
      (e.ctrlKey and e.which == 36) or    # ctrl + début
      (e.ctrlKey and e.which == 35)    # ctrl + fin
    )
    if importantKey
      S.userScroll = true;

  # Détecter le défilement de l'utilisateur via la souris
  # Mozilla/Webkit
  if window.addEventListener
      document.addEventListener('DOMMouseScroll', mouseEvent, false);

  # pour IE/OPERA etc
  document.onmousewheel = mouseEvent;

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