【问题标题】:jQuery: How can I improve this scrolling event that is being fired too many times?jQuery:如何改进这个被触发太多次的滚动事件?
【发布时间】:2015-08-16 12:08:18
【问题描述】:

此代码可以正常工作并且可以完成工作,但是它非常糟糕+基本并且在滚动事件方面存在一些问题。有人可以帮我优化滚动事件吗?

原型:http://codepen.io/rootion/pen/gpZZpG

结构和期望的行为:

  • 有两个容器,.layout__left(红色)和.layout__right(绿色)。
  • 绿色容器将具有主要内容并正常滚动。
  • 红色容器将具有导航功能,因此内容较少,并且应该只向上滚动到某个点,直到菜单到达页面边框。

这就是我正在做的事情:

  1. 首先两个容器都正常滚动。
  2. 向下滚动红色容器时,如果滚动位置+窗口大小大于 li:last 子位置(无论如何都想不到检测“底部”),则容器具有固定位置。
  3. 向上滚动时,固定位置被禁用,当菜单到达文档顶部时,位置再次固定,然后被移除。

正如我所说,这可以完成工作。但它很慢并且在滚动时会出现故障。我认为这是因为我正在处理滚动事件并且它在每个像素中都被执行。

我尝试限制函数调用,但代码根本不起作用:

    $(window).on('scroll', function() {
    $.throttle(100, sectionScroll));
    });

    sectionScroll = function() {
    var lastScrollTop = 0, delta = 5;
    var left = $('.layout__left');
    var right = $('.layout__right');
    var scroll = $(this).scrollTop();
    var viewport = $(window).height();
    var lastChild = $('.navigation > ul > li:last-child').offset().top;

    if(Math.abs(lastScrollTop - scroll) <= delta)
    return;

    if (scroll > lastScrollTop){
    // SCROLL DOWN
    left.removeClass('top absolute');

    // if the last item of the left is visible
    if (  (scroll + viewport) > (lastChild + 30)  ) {
    // make the left fixed
    left.addClass('fixed bottom');
    console.log("bottom!");
    }

    // SCROLL UP
    } else {
    // remove fixed class from left
    left.removeClass('fixed bottom');
    left.addClass('absolute bottom');

    if ( scroll <= left.position().top   ) {
    left.removeClass('bottom absolute');
    left.addClass('top fixed');
    left.removeClass('top fixed');
    console.log("top!");
    }
    }

    lastScrollTop = scroll;
    };

有什么反馈吗?

【问题讨论】:

  • 您的 codepen 代码与本文中的代码不匹配。
  • 至少在您发布的代码中,您正在运行 $.throttle(100, sectionScroll));每次 xy 坐标甚至有一个像素变化。这将运行很多,甚至可能重复。
  • 也许这会有所帮助? stackoverflow.com/a/9617517/1090538

标签: jquery scroll


【解决方案1】:

您可以这样做的一种方法是将其放在脚本中的某个位置:

var isStarted = false;

然后,在你的启动函数中:

if(!isStarted) {
    isStarted = true;
//other stuff
} else {
    return false; //because it's already doing it's thing
}

在您的停止功能中:

isStarted = false;

【讨论】:

    猜你喜欢
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 2020-05-07
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多