web-dev-qa-db-fra.com

Evénement déclencheur lorsque l'utilisateur fait défiler jusqu'à un élément spécifique - avec jQuery

J'ai un h1 qui est loin en bas d'une page ..

<h1 id="scroll-to">TRIGGER EVENT WHEN SCROLLED TO.</h1>

et je veux déclencher une alerte lorsque l'utilisateur sélectionne le h1 ou l'a affichée dans la vue de son navigateur.

$('#scroll-to').scroll(function() {
     alert('you have scrolled to the h1!');
});

comment puis-je faire cela?

63
Karl Coelho

Vous pouvez calculer la offset de l'élément, puis la comparer à la valeur scroll comme:

$(window).scroll(function() {
   var hT = $('#scroll-to').offset().top,
       hH = $('#scroll-to').outerHeight(),
       wH = $(window).height(),
       wS = $(this).scrollTop();
   if (wS > (hT+hH-wH)){
       console.log('H1 on the view!');
   }
});

Vérifiez ceci Demo Fiddle


Mis à jour Démo Violon aucune alerte - à la place FadeIn () l'élément


Code mis à jour pour vérifier si l'élément est dans la fenêtre ou non. Ainsi, cela fonctionne que vous fassiez défiler vers le haut ou le bas en ajoutant des règles à l'instruction if:

   if (wS > (hT+hH-wH) && (hT > wS) && (wS+wH > hT+hH)){
       //Do something
   }

Demo Fiddle

117
DaniP

Combinant cette question avec la meilleure réponse de action de déclenchement de jQuery lorsqu'un utilisateur fait défiler une certaine partie de la page

var element_position = $('#scroll-to').offset().top;

$(window).on('scroll', function() {
    var y_scroll_pos = window.pageYOffset;
    var scroll_pos_test = element_position;

    if(y_scroll_pos > scroll_pos_test) {
        //do stuff
    }
});

UPDATE

J'ai amélioré le code pour qu'il se déclenche lorsque l'élément est à mi-hauteur de l'écran plutôt que tout en haut. Le code sera également déclenché si l'utilisateur appuie en bas de l'écran et que la fonction ne s'est pas encore déclenchée.

var element_position = $('#scroll-to').offset().top;
var screen_height = $(window).height();
var activation_offset = 0.5;//determines how far up the the page the element needs to be before triggering the function
var activation_point = element_position - (screen_height * activation_offset);
var max_scroll_height = $('body').height() - screen_height - 5;//-5 for a little bit of buffer

//Does something when user scrolls to it OR
//Does it when user has reached the bottom of the page and hasn't triggered the function yet
$(window).on('scroll', function() {
    var y_scroll_pos = window.pageYOffset;

    var element_in_view = y_scroll_pos > activation_point;
    var has_reached_bottom_of_page = max_scroll_height <= y_scroll_pos && !element_in_view;

    if(element_in_view || has_reached_bottom_of_page) {
        //Do something
    }
});
24
Daniel Tonon

Je pense que votre meilleur pari serait de tirer parti d'une bibliothèque existante qui fait exactement cela:

http://imakewebthings.com/jquery-waypoints/

Vous pouvez ajouter des écouteurs à vos éléments qui se déclencheront lorsque votre élément atteindra le sommet de la fenêtre:

$('#scroll-to').waypoint(function() {
 alert('you have scrolled to the h1!');
});

Pour une démo incroyable en cours d'utilisation:

http://tympanus.net/codrops/2013/07/16/on-scroll-header-effects/

7
Mister Epic

Evénement déclenché par la bibliothèque Inview et fonctionne bien avec jquery 1.8 et supérieur! https://github.com/protonet/jquery.inview

$('div').on('inview', function (event, visible) {
  if (visible == true) {
    // element is now visible in the viewport
  } else {
    // element has gone out of viewport
  }
});

Lisez ceci https://remysharp.com/2009/01/26/element-in-view-event-plugin

5
Dima Melnik

Cela devrait être ce dont vous avez besoin.

Javascript:

$(window).scroll(function() {
    var hT = $('#circle').offset().top,
        hH = $('#circle').outerHeight(),
        wH = $(window).height(),
        wS = $(this).scrollTop();
    console.log((hT - wH), wS);
    if (wS > (hT + hH - wH)) {
        $('.count').each(function() {
            $(this).prop('Counter', 0).animate({
                Counter: $(this).text()
            }, {
                duration: 900,
                easing: 'swing',
                step: function(now) {
                    $(this).text(Math.ceil(now));
                }
            });
        }); {
            $('.count').removeClass('count').addClass('counted');
        };
    }
});

CSS:

#circle
{
    width: 100px;
    height: 100px;
    background: blue;
    -moz-border-radius: 50px;
    -webkit-border-radius: 50px;
    border-radius: 50px;
    float:left;
    margin:5px;
}
.count, .counted
{
  line-height: 100px;
  color:white;
  margin-left:30px;
  font-size:25px;
}
#talkbubble {
   width: 120px;
   height: 80px;
   background: green;
   position: relative;
   -moz-border-radius:    10px;
   -webkit-border-radius: 10px;
   border-radius:         10px;
   float:left;
   margin:20px;
}
#talkbubble:before {
   content:"";
   position: absolute;
   right: 100%;
   top: 15px;
   width: 0;
   height: 0;
   border-top: 13px solid transparent;
   border-right: 20px solid green;
   border-bottom: 13px solid transparent;
}

HTML:

<div id="talkbubble"><span class="count">145</span></div>
<div style="clear:both"></div>
<div id="talkbubble"><span class="count">145</span></div>
<div style="clear:both"></div>
<div id="circle"><span class="count">1234</span></div>

Vérifiez cette bootply: http://www.bootply.com/atin_agarwal2/cJBywxX5Qp

2
Atin Agarwal

Vous pouvez utiliser plugin jQuery avec l'événement inview comme ceci:

jQuery('.your-class-here').one('inview', function (event, visible) {
    if (visible == true) {
      //Enjoy !
    }
});

Lien: https://remysharp.com/2009/01/26/element-in-view-event-plugin

2
Mehdi

Si vous utilisez beaucoup de fonctionnalités basées sur la position du défilement, la magie Scroll ( http://scrollmagic.io/ ) est entièrement conçue à cet effet.

Cela facilite le déclenchement de JS en fonction du moment où l'utilisateur atteint certains éléments lors du défilement. Il s'intègre également avec le moteur d'animation GSAP ( https://greensock.com/ ), ce qui est idéal pour les sites Web à défilement parallèle.

1
Daniel Tonon

Juste une modification rapide de la réponse de DaniP, pour tous ceux qui travaillent avec des éléments pouvant parfois dépasser les limites de la fenêtre d'affichage de l'appareil.

Ajout d'un simple conditionnel - Dans le cas d'éléments plus grands que la fenêtre d'affichage, l'élément sera révélé une fois que sa moitié supérieure aura complètement rempli la fenêtre d'affichage.

function elementInView(el) {
  // The vertical distance between the top of the page and the top of the element.
  var elementOffset = $(el).offset().top;
  // The height of the element, including padding and borders.
  var elementOuterHeight = $(el).outerHeight();
  // Height of the window without margins, padding, borders.
  var windowHeight = $(window).height();
  // The vertical distance between the top of the page and the top of the viewport.
  var scrollOffset = $(this).scrollTop();

  if (elementOuterHeight < windowHeight) {
    // Element is smaller than viewport.
    if (scrollOffset > (elementOffset + elementOuterHeight - windowHeight)) {
      // Element is completely inside viewport, reveal the element!
      return true;
    }
  } else {
    // Element is larger than the viewport, handle visibility differently.
    // Consider it visible as soon as it's top half has filled the viewport.
    if (scrollOffset > elementOffset) {
      // The top of the viewport has touched the top of the element, reveal the element!
      return true;
    }
  }
  return false;
}
1
Allan of Sydney

Vous pouvez l'utiliser pour tous les appareils,

$(document).on('scroll', function() {
    if( $(this).scrollTop() >= $('#target_element').position().top ){
        do_something();
    }
});
1
user3444748

Faites défiler une seule fois après un défilement réussi

La réponse acceptée a fonctionné pour moi (90%), mais je devais la modifier un peu pour pouvoir tirer une seule fois.

$(window).on('scroll',function() {
            var hT = $('#comment-box-section').offset().top,
                hH = $('#comment-box-section').outerHeight(),
                wH = $(window).height(),
                wS = $(this).scrollTop();

            if (wS > ((hT+hH-wH)-500)){
                console.log('comment box section arrived! eh');
                // After Stuff
                $(window).off('scroll');
                doStuff();
            }

        });

Note: Par défilement réussi, je veux dire lorsque l'utilisateur a fait défiler mon élément ou, en d'autres termes, lorsque mon élément est en vue.

0
Junaid