Debounce jquery 滚动事件
Debounce jquery scroll events
我只是有一个关于去抖动的一般性问题。我在页面上的不同位置有三个菜单,当它们到达距离滚动 window 顶部 85px 的位置时,它们就会固定。它们在到达顶部时分层重叠。我目前为每个函数都有一个函数,并希望尽可能地进行优化。我的阅读表明 .offset.top 计算非常费力。
我的问题是:我是不是想多了,在这种情况下是否有必要去抖动?如果我的解释是正确的,则三个偏移量计算会在滚动时不断执行。任何人都可以建议优化或解释为什么它不是必需的。
谢谢。
$(function(){
// Check the initial Position of the fixed_nav_container
var stickyHeaderTop0 = $('.fixed_heading_shop').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'});
}
});
});
$(function(){
// Check the initial Position of the fixed_nav_container
var stickyHeaderTop1 = $('.fixed_heading_pricetable').offset().top;
$(window).scroll(function(){
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'});
}
});
});
$(function(){
// Check the initial Position of the fixed_nav_container
var stickyHeaderTop2 = $('.fixed_heading_layout').offset().top;
$(window).scroll(function(){
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'});
}
});
});
对于这种情况,我认为这确实是一个偏好问题。查看网站在给定情况下的响应方式,如果您觉得用户体验受到负面影响,请进行调整。我倾向于 throttle/debounce 滚动事件。
您可以采取一些措施来(稍微)加快滚动处理程序的速度。如果您可以使用 id,例如 jQuery 对 optimizing selectors 的指南,例如$('#myElement')
很快,因为它使用 document.getElementById
.
如果您担心性能,请进行更多细微调整:如果不需要调用,请不要调用任何调整 css。即如果自上次触发滚动处理程序以来没有任何变化。 (参见 isFixed
布尔值)
$(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));
});
唯一重复的调用是 $(window).scrollTop()
,如果您可以组合所有滚动处理程序(3 个?),那么每个 [throttled] 滚动事件只需要调用一次。
在不对 HTML 标记进行任何更改的情况下,您可以稍微优化一下代码:
$(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'});
}
});
});
如果你给三个元素一个共同的class,if..else 功能相同,那么它会更优化。
我在 JS 中添加了一个 class 'common',你可以在 html 本身添加它。
$(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'});
}
});
});
});
我会说,与其尝试直接设置 css,不如利用 类。
.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');
}
});
});
我只是有一个关于去抖动的一般性问题。我在页面上的不同位置有三个菜单,当它们到达距离滚动 window 顶部 85px 的位置时,它们就会固定。它们在到达顶部时分层重叠。我目前为每个函数都有一个函数,并希望尽可能地进行优化。我的阅读表明 .offset.top 计算非常费力。
我的问题是:我是不是想多了,在这种情况下是否有必要去抖动?如果我的解释是正确的,则三个偏移量计算会在滚动时不断执行。任何人都可以建议优化或解释为什么它不是必需的。
谢谢。
$(function(){
// Check the initial Position of the fixed_nav_container
var stickyHeaderTop0 = $('.fixed_heading_shop').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'});
}
});
});
$(function(){
// Check the initial Position of the fixed_nav_container
var stickyHeaderTop1 = $('.fixed_heading_pricetable').offset().top;
$(window).scroll(function(){
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'});
}
});
});
$(function(){
// Check the initial Position of the fixed_nav_container
var stickyHeaderTop2 = $('.fixed_heading_layout').offset().top;
$(window).scroll(function(){
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'});
}
});
});
对于这种情况,我认为这确实是一个偏好问题。查看网站在给定情况下的响应方式,如果您觉得用户体验受到负面影响,请进行调整。我倾向于 throttle/debounce 滚动事件。
您可以采取一些措施来(稍微)加快滚动处理程序的速度。如果您可以使用 id,例如 jQuery 对 optimizing selectors 的指南,例如$('#myElement')
很快,因为它使用 document.getElementById
.
如果您担心性能,请进行更多细微调整:如果不需要调用,请不要调用任何调整 css。即如果自上次触发滚动处理程序以来没有任何变化。 (参见 isFixed
布尔值)
$(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));
});
唯一重复的调用是 $(window).scrollTop()
,如果您可以组合所有滚动处理程序(3 个?),那么每个 [throttled] 滚动事件只需要调用一次。
在不对 HTML 标记进行任何更改的情况下,您可以稍微优化一下代码:
$(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'});
}
});
});
如果你给三个元素一个共同的class,if..else 功能相同,那么它会更优化。 我在 JS 中添加了一个 class 'common',你可以在 html 本身添加它。
$(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'});
}
});
});
});
我会说,与其尝试直接设置 css,不如利用 类。
.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');
}
});
});