根据滚动位置平滑固定元素的正确方法是什么? 我尝试取消滚动监听器的性能,但固定不准确。即使将反跳设置为10ms,它也不平滑,并且元素也不能干净地捕捉到其初始位置。
var scrolling = false;
var stickPosY = 100;
var heights = [];
$(".element").each( function(index) {
heights[index] = $(".element[data-trigger=" + index + "]").offset().top;
});
function pin() {
if ( !$("#aside").hasClass("fixed") ) {
var stickyLeft = $("#aside").offset().left;
var stickyWidth = $("#aside").outerWidth();
var stickyTop = $("#aside").offset().top - stickPosY;
$("#aside").addClass("fixed");
$("#aside").css({"left": stickyLeft, "top": stickyTop, "width": stickyWidth});
}
}
function unpin() {
$("#aside").css({"left": "", "top": "", "width": ""});
$("#aside").removeClass("fixed")
}
$( window ).scroll( function() {
scrolling = true;
});
setInterval( function() {
if ( scrolling ) {
scrolling = false;
var y = window.scrollY;
console.log(y);
// PIN SIDEBAR
y > stickPosY ? pin() : unpin();
//TRIGGERS
for (var i=0; i < heights.length; i++) {
if (y >= heights[i]) {
$('.element[data-trigger="' + i + '"]').addClass("blue");
}
else {
$('.element[data-trigger="' + i + '"]').removeClass("blue");
}
}
}
}, 250 );
这是我的Pen
我尝试将scrollMagic用于带有引脚和其他触发器的场景中的项目,但滚动不是很流畅。因此,我正在尝试使用精简版和侦听器反弹来重建它。这种方法可行吗?还是我应该尝试优化scrollMagic场景?
答案 0 :(得分:0)
您可以尝试fixed or sticky CSS positioning:
#element {
position: fixed;
top: 80px;
left: 10px;
}
位置:固定后,无论滚动位置如何,该元素始终始终保持顶部80像素和左侧10像素。
#element{
position: sticky;
top: 0;
right: 0;
left: 0;
}
这是我的一个项目。元素是导航栏。它位于标题栏下方,因此当您位于页面顶部时,您会看到标题,然后是其下方的导航栏;向下滚动时,标题移出屏幕,但导航栏会停留在顶部,并且始终可见
答案 1 :(得分:0)
正如James指出的那样,您只能使用position: sticky
作为一个选项,但这在旧版浏览器中不起作用,并且它的使用仅限于新版浏览器中的简单情况,因此我将继续使用JS假设您想走那条路线的解决方案。
您的JS中发生了很多事情,我认为您可能使事情复杂化了,所以我将为您提供一些基础知识。
当您基于滚动切换内容时,可以切换内联样式或类,但不能同时切换两者。我建议切换一个类,因为它允许您使用一个可以在多种屏幕尺寸上使用的功能(即您可以使用媒体查询根据屏幕尺寸来更改切换后的类的行为)。还将所有样式保留在一个位置,而不是在JS和样式表之间分割样式。
尽量保持滚动状态,同时尽量减少滚动。例如,对滚动功能之外的变量中的元素的引用进行高速缓存,以便您不必在每次滚动像素时都不断查找它们。避免滚动功能内部循环。
通常不建议使用setInterval
来提高滚动功能的性能。不管您是否滚动,所有需要做的就是每隔X时间运行一次函数。您真正想做的是直接限制滚动功能的速率。这样,如果您真正快速地滚动很长一段距离,您的函数将仅被调用,否则它将被称为总次数的一部分,但是如果您缓慢滚动一小段距离,它仍将被称为保持事物最少的次数看起来很平滑,如果根本不滚动,那么根本就不会调用函数。另外,在这种情况下,您可能想节制功能,而不是对其进行反跳操作。
考虑使用Underscore.js或Lodash.js中的节流功能,而不要发明自己的功能,因为这些功能高效能并且可以在各种浏览器上使用。
这是一个简单的示例,在滚动时将元素粘贴到屏幕顶部,并受Lodash限制。我正在使用25ms的油门,这是我为保持外观平滑而建议的最大数量,当您滚动阈值时不会真正注意到元素粘连/不粘连的延迟。您可能会低至10毫秒。
$(function() {
$(window).on('scroll', _.throttle(toggleClass, 25));
const myThing = $('#my-thing');
const threshold = $('#dummy-1').height();
function toggleClass() {
const y = window.scrollY;
if (y > threshold) {
myThing.addClass('stuck')
} else {
myThing.removeClass('stuck');
}
}
});
#dummy-1 {
height: 150px;
background-color: steelblue;
}
#dummy-2 {
height: 150px;
background-color: gold;
}
#my-thing {
width: 300px;
height: 75px;
background-color: firebrick;
position: absolute;
top: 150px;
left: 0;
}
#my-thing.stuck {
position: fixed;
top: 0;
}
body {
margin: 0;
height: 2000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.0.0/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="dummy-1"></div>
<div id="dummy-2"></div>
<div id="my-thing"></div>