如何避免滚动条滚动时,onscroll事件的频繁触发?

在如下的吸顶效果的代码中,当滚动条滚动时,会频繁触发事件,导致红条div一闪一闪的,请问该如何解决这个问题?(貌似需要用到防抖和节流的知识,可否分别给出利用防抖和节流的方法)

点击↓
https://jsfiddle.net/20170808...

$(window).scroll(function () {
  if($(window).scrollTop() > $('div').offset().top){
    $('div').css('position','fixed');
    $('div').css('top',0);
  }else{
    $('div').css('position','absolute');
    $('div').css('top',170);
  }
});
阅读 12.5k
10 个回答

这个跟scroll事件的刷新频率没有半毛钱关系,而是$('div').offset().top放在scroll事件里,每次滚动,都会重新计算div离顶部的距离,导致抖动,只需要事件开始前保存div的起始top值即可,代码如下:
主要是加粗部分:

const 
  $win = $(window),
  $panel = $('.panel');

// 先记录初始panel的位置
**const panel_top = $panel.offset().top;**

$win.on('scroll', (e) => {
  let css;
  if ($win.scrollTop() > panel_top) {
    css = {
      position: 'fixed',
      top: 0
    };
  } else {
    css = {
      position: 'absolute',
      top: panel_top
    }
  }
  $panel.css(css);
});

预览:https://codepen.io/IKobeCan/f...

搜underscore的方法吧

// 节流函数,我直接从lodash中引入,你可以用其他的库
var throttle = require('lodash/throttle')
var scrollHandler = function () {
  if($(window).scrollTop() > $('div').offset().top){
    $('div').css('position','fixed');
    $('div').css('top',0);
  }else{
    $('div').css('position','absolute');
    $('div').css('top',170);
  }
}
$(window).scroll(throttle(scrollHandler, 50))
新手上路,请多包涵

可以嵌套一层定时器达到函数节流效果
至于你说的红条DIV一闪一闪 给的链接无法访问 看不到问题

@Render 指出问题的根源,但这里还会有一个问题,就是当快速滚动时会引起掉帧问题,因为 scroll 事件滚动中实在太频繁了

https://jsfiddle.net/u4d4dz8y/6/

闪的原因是 第一个判断 执行完了后 if($(window).scrollTop() > $('div').offset().top){ 这个判断里的两个值相等了 下次执行 执行到else 里面去了吧
$('div').offset().top 这个值 不是 固定的 一直在变化吧

新手上路,请多包涵

因为div在绝对定位和固定定位之前不断的切换,所以会闪烁

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题