jquery - 在 jquery 中处理 $(window).scroll 函数的更有效方法?

标签 jquery scroll

在下面的代码中,我检查窗口是否滚动到某个点,如果是,则将元素更改为使用固定位置,以便它不会滚动到页面顶部。唯一的问题是,这似乎是高度客户端内存密集型(并且确实降低了滚动速度),因为在每个滚动像素上,我都会一遍又一遍地更新元素上的样式属性。

在尝试更新之前检查 attr 是否已经存在会产生重大影响吗?是否有完全不同且更有效的做法来获得相同的结果?

$(window).scroll(function () {
    var headerBottom = 165;
    var fcHeight = $("#pnlMainNavContainer").height();

    var ScrollTop = $(window).scrollTop();
    if (ScrollTop > headerBottom) {
        $("#HeaderContentBuffer").attr("style", "margin-top:" + (fcHeight) + "px;");
        $("#AddFieldsContainer").attr("style", "position:fixed;width:320px;top:70px;left:41px;");
    } else {
        $("#HeaderContentBuffer").attr("style", "margin-top: 0px;");
        $("#AddFieldsContainer").removeAttr("style");
    }
});

当我输入此内容时,我注意到 StackOverflow.com 使用相同类型的功能,并在该页面右侧使用黄色的“类似问题”和“帮助”菜单。我想知道他们是如何做到的。

最佳答案

您可以使用的一种技术是在滚动事件上设置一个计时器,并且仅在滚动位置短时间内没有更改时才执行主要工作。我在调整具有相同问题的事件大小时使用该技术。您可以尝试一下合适的超时值。较短的时间以较短的滚动暂停进行更新,因此在滚动期间可能会更频繁地运行,较长的时间需要用户实际暂停所有运动一段有意义的时间。您必须尝试什么超时值最适合您的目的,并且最好在相对较慢的计算机上进行测试,因为这就是滚动滞后问题最明显的地方。

以下是如何实现这一点的总体思路:

var scrollTimer = null;
$(window).scroll(function () {
    if (scrollTimer) {
        clearTimeout(scrollTimer);   // clear any previous pending timer
    }
    scrollTimer = setTimeout(handleScroll, 500);   // set new timer
});

function handleScroll() {
    scrollTimer = null;
    var headerBottom = 165;
    var fcHeight = $("#pnlMainNavContainer").height();

    var ScrollTop = $(window).scrollTop();
    if (ScrollTop > headerBottom) {
        $("#HeaderContentBuffer").attr("style", "margin-top:" + (fcHeight) + "px;");
        $("#AddFieldsContainer").attr("style", "position:fixed;width:320px;top:70px;left:41px;");
    } else {
        $("#HeaderContentBuffer").attr("style", "margin-top: 0px;");
        $("#AddFieldsContainer").removeAttr("style");
    }
}

您还可以通过在滚动首次开始时缓存一些选择器来加速滚动功能,这样就不必每次都重新计算它们。在这里,每次创建 jQuery 对象的额外开销可能对您没有帮助。

<小时/>

这里有一个 jQuery 附加方法,可以为您处理滚动计时器:

(function($) {
    var uniqueCntr = 0;
    $.fn.scrolled = function (waitTime, fn) {
        if (typeof waitTime === "function") {
            fn = waitTime;
            waitTime = 500;
        }
        var tag = "scrollTimer" + uniqueCntr++;
        this.scroll(function () {
            var self = $(this);
            var timer = self.data(tag);
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(function () {
                self.removeData(tag);
                fn.call(self[0]);
            }, waitTime);
            self.data(tag, timer);
        });
    }
})(jQuery);

工作演示:http://jsfiddle.net/jfriend00/KHeZY/

您的代码将像这样实现:

$(window).scrolled(function() {
    var headerBottom = 165;
    var fcHeight = $("#pnlMainNavContainer").height();

    var ScrollTop = $(window).scrollTop();
    if (ScrollTop > headerBottom) {
        $("#HeaderContentBuffer").attr("style", "margin-top:" + (fcHeight) + "px;");
        $("#AddFieldsContainer").attr("style", "position:fixed;width:320px;top:70px;left:41px;");
    } else {
        $("#HeaderContentBuffer").attr("style", "margin-top: 0px;");
        $("#AddFieldsContainer").removeAttr("style");
    }
});

关于jquery - 在 jquery 中处理 $(window).scroll 函数的更有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7392058/

相关文章:

动态容器内 div 的 css 滚动条

html - 在隐藏的溢出 div 内滚动 div

html - 使滚动条在太大的内容上保持可见

javascript - 从 javascript 发送 DataTables 中的 JSON 对象

javascript - 使用单个文本框在其他框中输入值

javascript - Jquery追加方法

javascript - 动态创建 html div jinja2 和 ajax

java - android Horizo​​ntalScrollView 中左右滚动的按钮

ios - 我如何在单元格加载时淡入淡出?