我有一个元素,向下滚动时希望保留在页面顶部。从功能上讲,所有代码都能正常工作,这要归功于SO上的另一个用户。但是,在手机上向下滚动时,粘性元素似乎滞后了一点。我的意思是,每次父元素滚动时,代码似乎都会调用一次,这会导致对粘性元素进行数百或数千次调整,从而使它有些动摇。
这是下面的代码:
HTML
<div id="scroller-wrapper">
<div id="scroller-anchor"></div>
<div id="scroller" class="row visible-xs-block meal-controls">
My sticky element is here and working
</div>
</div>
JS
$('#scroller-wrapper').scroll(function() {
var $anchor = $("#scroller-anchor");
var $scroller = $('#scroller');
var move = function() {
var st = $(window).scrollTop();
var ot = $anchor.offset().top;
if(st > ot) {
$scroller.addClass('fixedElement');
} else {
$scroller.removeClass('fixedElement');
}
};
$(window).scroll(move);
move();
});
CSS
.fixedElement {
position:fixed;
top:0;
right:0;
width:100%;
z-index:10000;
}
答案 0 :(得分:0)
您需要做的是throttle
或debounce
调用以更新元素。
为什么还要在包装滚动处理程序内部将滚动侦听器附加到window
?这意味着每次调用滚动侦听器时,都会将另一个滚动侦听器附加到window
。
您需要的只是窗口上的单个处理程序,并允许传播来完成其余的操作。
// A debounce function wraps a function with a setTimeout,
// and then resets that timeout everytime it is called
function debounce(func, delay){
var timeout, that = this;
delay = delay || 300;
return function() {
if(timeout) clearTimeout(timeout)
timeout = setTimeout(function() {
return func.apply(that, arguments)
}, delay)
}
}
// a throttle function ensures that a function isn't
// called more than once every interval
function throttle(fn, interval, shouldDebounce){
var lastCall = 0, debouncedFn;
interval = interval || 300
if(shouldDebounce) debouncedFn = debounce(fn, interval);
return function(){
var now = (new Date()).getTime();
if(now - lastCall < interval)
return debouncedFn && debouncedFn.apply(this, arguments);
lastCall = now;
return fn.apply(this, arguments);
}
}
// create a function to set scroll listeners
function setScroller() {
var $anchor = $("#scroller-anchor"),
$scroller = $('#scroller'),
onMove = function onMove() {
var st = $(window).scrollTop(),
ot = $anchor.offset().top;
if(st > ot) {
$scroller.addClass('fixedElement');
} else {
$scroller.removeClass('fixedElement');
}
},
// Throttle the onMove function to make sure it isn't called too often
throttlededOnMove = throttle(onMove, 300);
$(window).scroll(throttlededOnMove);
}
// attach scroll listener on document ready
$(setScroller)
答案 1 :(得分:0)
IMO,一种可能且更有效的解决方案是在CSS中使用position: sticky
,而不是JS。您还需要提供top: 0
。 IE中的某些兼容性落后,但它已经是可行的解决方案。值得检查out here
如果您担心旧的浏览器,可以在JS中添加一个后备功能,该功能仍然有些落后