【问题标题】:Add/remove class with jquery based on vertical scroll?基于垂直滚动的jquery添加/删除类?
【发布时间】:2012-09-15 12:23:14
【问题描述】:

所以基本上我想在用户向下滚动一点后从“标题”中删除该类并添加另一个类来改变它的外观。

试图找出最简单的方法,但我无法做到。

$(window).scroll(function() {    
    var scroll = $(window).scrollTop();    
    if (scroll <= 500) {
        $(".clearheader").removeClass("clearHeader").addClass("darkHeader");
    }
}

CSS

.clearHeader{
    height: 200px; 
    background-color: rgba(107,107,107,0.66);
    position: fixed;
    top:200;
    width: 100%;   
}    

.darkHeader { height: 100px; }

.wrapper {
    height:2000px;
}

HTML

<header class="clearHeader">    </header>
<div class="wrapper">     </div>

我确定我在做一些非常基本的错误。

【问题讨论】:

标签: javascript jquery css


【解决方案1】:

这个值是有意的吗? if (scroll &lt;= 500) { ... 这意味着它发生在 0 到 500 之间,而不是 500 或更大。在原始帖子中,您说“在用户向下滚动一点之后”

【讨论】:

    【解决方案2】:
    $(window).scroll(function() {    
        var scroll = $(window).scrollTop();
    
         //>=, not <=
        if (scroll >= 500) {
            //clearHeader, not clearheader - caps H
            $(".clearHeader").addClass("darkHeader");
        }
    }); //missing );
    

    Fiddle

    此外,通过删除 clearHeader 类,您将从元素中删除 position:fixed; 以及通过 $(".clearHeader") 选择器重新选择它的能力。我建议不要删除该类并在其上添加一个新的 CSS 类以进行样式设置。

    如果您想在用户向上滚动时“重置”类添加:

    $(window).scroll(function() {    
        var scroll = $(window).scrollTop();
    
        if (scroll >= 500) {
            $(".clearHeader").addClass("darkHeader");
        } else {
            $(".clearHeader").removeClass("darkHeader");
        }
    });
    

    Fiddle

    编辑: 这是缓存标题选择器的版本 - 性能更好,因为它不会在每次滚动时查询 DOM,并且您可以安全地删除/添加任何类到标题元素而不会丢失引用:

    $(function() {
        //caches a jQuery object containing the header element
        var header = $(".clearHeader");
        $(window).scroll(function() {
            var scroll = $(window).scrollTop();
    
            if (scroll >= 500) {
                header.removeClass('clearHeader').addClass("darkHeader");
            } else {
                header.removeClass("darkHeader").addClass('clearHeader');
            }
        });
    });
    

    Fiddle

    【讨论】:

    • 好吧,我可以将 position:fixed 添加到 darkHeader 类,这就是我的意图。现在的问题是,在用户向上滚动后,我无法将它们再次交换回来。
    • 那是因为您从选择器中删除了该类。在我更新小提琴时,您可以轻松缓存标题。
    • 谢谢,Fab,我的方法也行,但这样做是不是很傻?
    • @andy 不,事实上我打算发布它。这是一种不存储任何不必要的变量而是在每次滚动页面时查询 DOM 的好方法。这是另一种替代方式:fiddle
    • 感谢您的帮助,我想我会使用您的。
    【解决方案3】:

    如果你喜欢,可以添加一些过渡效果:

    http://jsbin.com/boreme/17/edit?html,css,js

    .clearHeader {
      height:50px;
      background:lightblue;
      position:fixed;
      top:0;
      left:0;
      width:100%;
    
      -webkit-transition: background 2s; /* For Safari 3.1 to 6.0 */
      transition: background 2s;
    }
    
    .clearHeader.darkHeader {
     background:#000;
    }
    

    【讨论】:

      【解决方案4】:

      这是我的代码

      jQuery(document).ready(function(e) {
          var WindowHeight = jQuery(window).height();
      
          var load_element = 0;
      
          //position of element
          var scroll_position = jQuery('.product-bottom').offset().top;
      
          var screen_height = jQuery(window).height();
          var activation_offset = 0;
          var max_scroll_height = jQuery('body').height() + screen_height;
      
          var scroll_activation_point = scroll_position - (screen_height * activation_offset);
      
          jQuery(window).on('scroll', function(e) {
      
              var y_scroll_pos = window.pageYOffset;
              var element_in_view = y_scroll_pos > scroll_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) {
                  jQuery('.product-bottom').addClass("change");
              } else {
                  jQuery('.product-bottom').removeClass("change");
              }
      
          });
      
      });
      

      工作正常

      【讨论】:

        【解决方案5】:

        对于 Android 移动设备,$(window).scroll(function() 和 $(document).scroll(function() 可能有效,也可能无效。因此请改用以下内容。

        jQuery(document.body).scroll(function() {
                var scroll = jQuery(document.body).scrollTop();
        
                if (scroll >= 300) {
                    //alert();
                    header.addClass("sticky");
                } else {
                    header.removeClass('sticky');
                }
            });
        

        这段代码对我有用。希望它会帮助你。

        【讨论】:

          【解决方案6】:

          在类似的情况下,我想避免由于性能问题而总是调用 addClass 或 removeClass。我将滚动处理函数拆分为两个单独的函数,根据当前状态使用。我还根据这篇文章添加了去抖功能:https://developers.google.com/web/fundamentals/performance/rendering/debounce-your-input-handlers

                  var $header = jQuery( ".clearHeader" );         
                  var appScroll = appScrollForward;
                  var appScrollPosition = 0;
                  var scheduledAnimationFrame = false;
          
                  function appScrollReverse() {
                      scheduledAnimationFrame = false;
                      if ( appScrollPosition > 500 )
                          return;
                      $header.removeClass( "darkHeader" );
                      appScroll = appScrollForward;
                  }
          
                  function appScrollForward() {
                      scheduledAnimationFrame = false;
                      if ( appScrollPosition < 500 )
                          return;
                      $header.addClass( "darkHeader" );
                      appScroll = appScrollReverse;
                  }
          
                  function appScrollHandler() {
                      appScrollPosition = window.pageYOffset;
                      if ( scheduledAnimationFrame )
                          return;
                      scheduledAnimationFrame = true;
                      requestAnimationFrame( appScroll );
                  }
          
                  jQuery( window ).scroll( appScrollHandler );
          

          也许有人觉得这很有帮助。

          【讨论】:

            【解决方案7】:

            纯javascript

            这是在滚动期间处理类的纯 javascript 示例。

            const navbar = document.getElementById('navbar')
            
            // OnScroll event handler
            const onScroll = () => {
            
              // Get scroll value
              const scroll = document.documentElement.scrollTop
            
              // If scroll value is more than 0 - add class
              if (scroll > 0) {
                navbar.classList.add("scrolled");
              } else {
                navbar.classList.remove("scrolled")
              }
            }
            
            // Use the function
            window.addEventListener('scroll', onScroll)
            #navbar {
              position: fixed;
              top: 0;
              left: 0;
              right: 0;
              width: 100%;
              height: 60px;
              background-color: #89d0f7;
              box-shadow: 0px 5px 0px rgba(0, 0, 0, 0);
              transition: box-shadow 500ms;
            }
            
            #navbar.scrolled {
              box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.25);
            }
            
            #content {
              height: 3000px;
              margin-top: 60px;
            }
            <!-- Optional - lodash library, used for throttlin onScroll handler-->
            <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
            <header id="navbar"></header>
            <div id="content"></div>

            一些改进

            您可能希望限制处理滚动事件,因为处理程序逻辑变得更加复杂,在这种情况下 throttle 来自 lodash lib 会派上用场。

            如果您正在做 spa,请记住,一旦不需要它们,您需要使用 removeEventListener 清除事件侦听器(例如,在组件的 onDestroy 生命周期挂钩期间,例如 Vue 的 destroyed(),或者可能是 useEffect React 钩子的返回函数)。

            使用 lodash 进行节流示例:

                // Throttling onScroll handler at 100ms with lodash
                const throttledOnScroll = _.throttle(onScroll, 100, {})
            
                // Use
                window.addEventListener('scroll', throttledOnScroll)
            

            【讨论】:

              【解决方案8】:

              这是基于@shahzad-yousuf 的回答,但我只需要在用户向下滚动时压缩菜单。我使用顶部容器滚动“屏幕外”的参考点来启动“挤压”

                <script type="text/javascript">
                  $(document).ready(function (e) {
                    //position of element
                    var scroll_position = $('div.mainContainer').offset().top;
                    var scroll_activation_point = scroll_position;
                    $(window).on('scroll', function (e) {
                      var y_scroll_pos = window.pageYOffset;
                      var element_in_view = scroll_activation_point < y_scroll_pos;
                      if (element_in_view) {
                        $('body').addClass("toolbar-compressed ");
                        $('div.toolbar').addClass("toolbar-compressed ");
                      } else {
                        $('body').removeClass("toolbar-compressed ");
                        $('div.toolbar').removeClass("toolbar-compressed ");
                      }
                    });
              
                  });   </script>
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-04-21
                • 1970-01-01
                • 2017-02-19
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多