【问题标题】:Trigger event when user scroll to specific element - with jQuery当用户滚动到特定元素时触发事件 - 使用 jQuery
【发布时间】:2014-02-28 22:52:36
【问题描述】:

我有一个位于页面下方的 h1..

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

我想在用户滚动到 h1 或将其显示在浏览器视图中时触发警报。

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

我该怎么做?

【问题讨论】:

    标签: javascript jquery html scroll scrollto


    【解决方案1】:

    我认为最好的办法是利用现有的库来做这件事:

    http://imakewebthings.com/waypoints/

    你可以为你的元素添加监听器,当你的元素到达视口顶部时触发:

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

    关于它的惊人使用演示:

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

    【讨论】:

    • 我已经试过了。它仅在您滚动 PAST 元素后触发。还有其他解决方案吗?
    • 这个解决方案可以很好地获取建议,我已经在生产中使用它。参考博客:liyao13.wordpress.com/2017/05/11/…
    【解决方案2】:

    您可以计算元素的offset,然后将其与scroll 值进行比较,例如:

    $(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!');
       }
    });
    

    检查这个Demo Fiddle


    更新了Demo Fiddle 没有警告 -- 改为 FadeIn() 元素


    更新了检查元素是否在视口内的代码。因此,无论您是向上还是向下滚动,都可以在 if 语句中添加一些规则:

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

    Demo Fiddle

    【讨论】:

    • 请去抖动!
    • 有没有像 jQuery Waypoint 这样的功能包库?
    • 感谢@DaniP。酷sn-p!
    • @ClosDesign 你可以使用.off()解绑事件jsfiddle.net/n4pdx/543
    • @DaniP 我刚刚做了,谢谢!感谢您的回答,对我帮助很大:)
    【解决方案3】:

    将此问题与jQuery trigger action when a user scrolls past a certain part of the 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
        }
    });
    

    更新

    我改进了代码,使其在元素位于屏幕一半而不是最顶部时触发。如果用户点击屏幕底部并且该函数尚未触发,它也会触发代码。

    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
        }
    });
    

    【讨论】:

      【解决方案4】:

      Inview 库触发的事件,并且适用于 jquery 1.8 及更高版本! 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
        }
      });
      

      阅读此https://remysharp.com/2009/01/26/element-in-view-event-plugin

      【讨论】:

        【解决方案5】:

        如果您要根据滚动位置执行大量功能,则 Scroll magic (http://scrollmagic.io/) 完全是为此目的而构建的。

        它可以很容易地根据用户在滚动时到达某些元素时触发 JS。它还集成了 GSAP 动画引擎 (https://greensock.com/),非常适合视差滚动网站

        【讨论】:

          【解决方案6】:

          您可以像这样将jQuery plugininview 事件一起使用:

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

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

          【讨论】:

            【解决方案7】:

            这应该是你需要的。

            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>
            

            检查这个引导: http://www.bootply.com/atin_agarwal2/cJBywxX5Qp

            【讨论】:

              【解决方案8】:

              对于处理有时可能超出设备视口范围的元素的任何人来说,只是对 DaniP 答案的快速修改。

              仅添加了一个小条件 - 对于大于视口的元素,一旦元素的上半部分完全填满视口,就会显示该元素。

              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;
              }
              

              【讨论】:

              • 我建议使用不那么神秘的变量名,即使接受的答案使用它们。
              【解决方案9】:

              您可以将其用于所有设备,

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

              【讨论】:

                【解决方案10】:

                我一直使用相同的代码来做这件事,所以添加了一个简单的 jquery 插件来做这件事。 480 字节长,速度快。仅在运行时分析绑定元素。

                https://www.npmjs.com/package/jquery-on-scrolled-to

                这将是 $('#scroll-to').onScrolledTo(0, function() { alert('you have scrolled to the h1!'); });

                如果需要在显示一半的 h1 时发出警报,请使用 0.5 而不是 0。

                【讨论】:

                  【解决方案11】:

                  仅在成功滚动后一次触发滚动

                  注意:成功滚动是指当用户滚动到所需的 元素,或者换句话说,当所需的元素在视图中时

                  接受的答案对我来说有 90% 的效果,所以我不得不稍微调整一下才能真正触发一次。

                  $(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');
                          // This detaches the scroll so doStuff() won't run more than once
                          $(window).off('scroll');
                          doStuff();
                      }
                  });
                  

                  【讨论】:

                    【解决方案12】:

                    Intersection Observer 可能是 IMO 最好的东西,没有任何外部库,它确实做得很好。

                    const options = {
                                root: null,
                                threshold: 0.25, // 0 - 1 this work as a trigger. 
                                rootMargin: '150px'
                            };
                    
                            const target = document.querySelector('h1#scroll-to');
                            const observer = new IntersectionObserver(
                               entries => { // each entry checks if the element is the view or not and if yes trigger the function accordingly
                                entries.forEach(() => {
                                    alert('you have scrolled to the h1!')
                                });
                            }, options);
                            observer.observe(target);
                    

                    【讨论】:

                      【解决方案13】:

                      如果您正在寻找 javascript 版本。您可以在滚动事件监听器上调用此方法。

                        showScrollTop = () =>{
                          const currentScrollPosition = window.pageYOffset; 
                          let elementID = 'service-selector'
                          const elementOffsetTop = document.getElementById(elementID).offsetTop
                      
                          if ( currentScrollPosition > elementOffsetTop){
                           // place your logic here 
                          } else {
                            // place your logic here 
                          }
                        }
                      
                        window.addEventListener('scroll', showScrollTop)
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-03-14
                        • 2022-11-15
                        • 2017-09-20
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多