我在我的网站上有一个简单的脚本,在用户开始滚动后添加一个css类到导航栏,并在用户返回页面顶部时删除它。
然而,这会导致大量的jank (fps延迟),并且100%的性能损失是不值得的。
有没有一种方法可以优化它,或者让它在不引起jank的情况下工作?
$(window).scroll(function() {
var scroll = $(window).scrollTop();
var navbar = $('#navbar');
if (scroll >= 40) {
navbar.addClass("navbar-border");
} else {
navbar.removeClass("navbar-border");
}
});如果没有,我会删除它。
谢谢!
发布于 2016-04-11 07:50:15
您的代码可能每秒访问DOM 100次,这是导致性能问题的原因,为了提高性能,您可以限制scroll事件,以便它通过使用超时来减少代码的执行,该超时首先解除Scroll事件的绑定,然后在一段延迟(阈值)后绑定它,增加阈值将导致代码执行的频率较低。
var navbar = $('#navbar-border');
var threshold = 100; // in milliseconds
function borderControl() {
console.log("run");
var scroll = $(window).scrollTop();
if (scroll >= 40) {
navbar.addClass("navbar-border");
} else {
navbar.removeClass("navbar-border");
}
}
function setScrollTimer() {
unbindScroll();
scrollTimer = window.setTimeout(function() {
bindScroll()
}, threshold);
}
function unbindScroll() {
$(window).unbind("scroll");
}
function bindScroll() {
$(window).scroll(function(e) {
setScrollTimer();
borderControl();
});
}
bindScroll();发布于 2016-04-11 08:55:35
通过将结果存储在全局变量中,或者至少将结果存储在scroll回调外部的变量中,可以缓存处理的结果,以减少处理的频率。
回调函数一开始就没有太多的改进空间。
var navbar = $('#navbar');
var navborder = false;
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (!navborder && scroll >= 40) {
navborder = true;
navbar.addClass("navbar-border");
} else if(navborder && scroll < 40) {
navborder = false;
navbar.removeClass("navbar-border");
}
});http://codepen.io/t3hpwninat0r/pen/yOvaGN
或者,您可以禁用滚动位置检查,然后设置一个计时器,以便在短暂延迟后重新启用它
var scrollTimer = 0;
$(window).scroll(function() {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(function() {
var scroll = $(window).scrollTop();
var navbar = $('#navbar');
if (scroll >= 40) {
navbar.addClass("navbar-border");
} else {
navbar.removeClass("navbar-border");
}
}, 100);
});http://codepen.io/t3hpwninat0r/pen/BKYLMb
如果用户继续滚动,计时器将继续重新启动,并且该功能仅在100ms计时器完成时才会运行。这个例子只给你的代码添加了4行代码,而没有做任何其他的修改。
我从以下答案中提取(阅读:抄袭)代码:https://stackoverflow.com/a/14092859/1160540
https://stackoverflow.com/questions/36536657
复制相似问题