Debounce jquery scroll events

后端 未结 3 2011
夕颜
夕颜 2020-12-21 13:01

I just have a general question about debouncing. I have three menus at different positions on the page that when they reach a position 85px from the top of the window on scr

相关标签:
3条回答
  • 2020-12-21 13:40

    For this case, I think it's really a matter of preference. Take a look at how the site responds in your given situation, and make adjustments if you feel the user experience is negatively affected. I tend to throttle/debounce scroll events.

    There are a few things you can do to speed up your scroll handlers (slightly). If you can use id's, for example, as in jQuery's guide to optimizing selectors, e.g. $('#myElement') is fast because it uses document.getElementById.

    More minor adjustments if you're worried about performance: Don't make any calls to adjust css if no call is needed. i.e. if nothing changed since the last time the scroll handler was fired. (See isFixed boolean)

    $(function(){
      var OFFSET = 85;
      var WAIT = 10;
    
      // Check the initial Position of the fixed_nav_container
      var stickyHeaderTop0 = $('.fixed_heading_shop').offset().top;
      var isFixed = false; // assuming that's the right default value
    
      $(window).scroll(_.throttle(function(){
        if($(window).scrollTop() > stickyHeaderTop0 - OFFSET) {
          if(!isFixed) {
            $('#fixed_heading_shop').css({position: 'fixed', top: OFFSET+'px'});
            $('#ghost_div0').css({display: 'block'});
            isFixed = true;
          }
        }
        else {
          if(isFixed) {
            $('#fixed_heading_shop').css({position: 'relative', top: '0px'});
            $('#ghost_div0').css({display: 'none'});
            isFixed = false;
          }
        }
      }, WAIT));
    });
    

    The only repeated call is $(window).scrollTop() and if you can combine all your scroll handlers (3?) then you would only need to make that call once per [throttled] scroll event.

    0 讨论(0)
  • 2020-12-21 13:52

    Without making any changes in HTML mark up, you can optimize your code a little:

    $(function(){
    // Check the initial Position of the fixed_nav_container
     var stickyHeaderTop0 = $('.fixed_heading_shop').offset().top;
     var stickyHeaderTop1 = $('.fixed_heading_pricetable').offset().top;
     var stickyHeaderTop2 = $('.fixed_heading_layout').offset().top;
     $(window).scroll(function(){
            if( $(window).scrollTop() > stickyHeaderTop0-85) {
                    $('.fixed_heading_shop').css({position: 'fixed', top: '85px'});  
                    $('.ghost_div0').css({display: 'block'});
            } else {
                    $('.fixed_heading_shop').css({position: 'relative', top: '0px'});
                    $('.ghost_div0').css({display: 'none'});
            }
            if( $(window).scrollTop() > stickyHeaderTop1-85 ) {
                    $('.fixed_heading_pricetable').css({position: 'fixed', top: '85px'});  
                    $('.ghost_div1').css({display: 'block'});       
            } else {
                    $('.fixed_heading_pricetable').css({position: 'relative', top: '0px'});
                    $('.ghost_div1').css({display: 'none'});    
            }
            if( $(window).scrollTop() > stickyHeaderTop2-85) {
                    $('.fixed_heading_layout').css({position: 'fixed', top: '85px'});  
                    $('.ghost_div2').css({display: 'block'});
            } else {
                    $('.fixed_heading_layout').css({position: 'relative', top: '0px'});
                    $('.ghost_div2').css({display: 'none'});
            }
     });
    });
    

    And if you give a common class to the three elements for which the if..else functionality is same, then it will be more optimized. I am adding a class 'common' here in JS, you can add it in html itself.

    $(function(){
    // add common class to elements
     $('.fixed_heading_shop, .fixed_heading_pricetable, .fixed_heading_layout').addClass('common');
     var elemArr = [];
     // Check the initial Position of the fixed_nav_container
     $('.common').each(function(index){
            elemArr.push($(this).offset().top);
     })
     $(window).scroll(function(){
         $('.common').each(function(index){
            if( $(window).scrollTop() > elemArr[index]) {
                    $(this).css({position: 'fixed', top: '85px'});  
                    $('.ghost_div'+index).css({display: 'block'});
            } else {
                    $(this).css({position: 'relative', top: '0px'});
                    $('.ghost_div'+index).css({display: 'none'});
            }
         });
     });
    });
    
    0 讨论(0)
  • 2020-12-21 13:58

    I would say, rather than trying to set the css directly, take advantage of classes.

    .fixed_heading_shop,
    .fixed_heading_pricetable {
      position:relative;
      top:0;
    }
    .ghost_div0,
    .ghost_div1 {
      display:block;
    }
    .scroll_trick .fixed_heading_shop,
    .scroll_trick .fixed_heading_pricetable {
      position:fixed;
      top:85px;
    }
    .scroll_trick .ghost_div0,
    .scroll_trick .ghost_div1 {
      display:none;
    }
    
    $(function(){
      var $window = $(window);
      var $body = $('body');
      var top = $('.fixed_heading_shop').offset().top-85;
    
      $window.scroll(function(){
        if( $window.scrollTop() > top) {
          $body.addClass('scroll_trick');
        } else {
          $body.removeClass('scroll_trick');
        }   
      });
    });
    
    0 讨论(0)
提交回复
热议问题