滚动事件侦听器 位置:更改高度的粘性元素会导致抖动的无限滚动



我在屏幕顶部有一个元素,带有position:sticky;和一个JS滚动EventListener,可以在卡住元素时添加stuck类(滚动y大于0)。

stuck在粘性元素内部制作一个元素(具有CSS过渡)以降低高度。

当您非常缓慢地滚动时,这种高度的变化会使Scrolly跳回零并删除stuck类,这会产生一个愉快的滚动循环,该循环是无限的,直到您更快地滚动并消除问题为止。

使用position: sticky时,我该如何使其平滑,您可以在这里看到它:

https://jsfiddle.net/27rzba5v/

这是因为您正在改变元素的高度,这会影响框模型,从而影响文档的尺寸。一个简单的修复方法是使用.wrap上的转换,而不是过渡其高度。最好通过GPU来处理动画变换和不透明度,而不是通过进行浏览器重新涂抹。

var lastScrollY = 0;
var ticking = false;
window.addEventListener('scroll', function(e) {
	lastScrollY = window.scrollY;
	if ( ! ticking ) {
		window.requestAnimationFrame(function() {
			console.log( lastScrollY );
			if ( lastScrollY > 0 ) {
				document.body.classList.add('stuck');
			} else {
				document.body.classList.remove('stuck');
			}
			ticking = false;
		});
		ticking = true;
	}
} );
body {
	margin: 0;
}
.wrap {
	background: #666;
	text-align: center;
	position: sticky;
	top: 0;
  transition: 0.5s; /* Move transition here */
  transform-origin: top left; /* Make sure transition happens from the top left */
}
.block {
	width: 80px;
	height: 80px;
	background: red;
	display: block;
}
.stuck .wrap { /* Transform wrap instead of block */
	transform: scaleY(.5); /* Change scale instead of height */
}
<div class="wrap">
	<span class="block"></span>
</div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ac lorem a metus tincidunt eleifend id in odio. Nam malesuada hendrerit tristique. Pellentesque id ornare elit, ac lobortis metus. Sed iaculis et nisi et consectetur. Proin pellentesque metus mi, quis fringilla mauris pulvinar et. Vivamus pharetra elit ligula, eu consectetur magna consequat nec. Donec sed enim sit amet augue malesuada varius id a libero. Nullam nec ante id justo elementum congue quis in purus. Integer finibus cursus volutpat. Donec non laoreet ipsum.
Maecenas id venenatis velit, eu feugiat dolor. Vestibulum malesuada erat ut turpis mattis vehicula. Vestibulum sem leo, cursus quis lacinia eu, tincidunt eu velit. Nulla odio elit, tristique vel bibendum vitae, placerat nec eros. Proin auctor id leo sed rutrum. Proin convallis erat sit amet neque aliquam vestibulum. Ut sodales vel nisl eu imperdiet.
Donec a porttitor dui, vitae ullamcorper nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam non elit eu elit blandit hendrerit id ut eros. Duis sagittis elementum ligula eu venenatis. Aenean nunc mauris, dignissim ut venenatis ac, pharetra eget magna. Curabitur elementum enim sed pharetra rhoncus. Praesent sodales at ex at consectetur. Curabitur sed dictum mi, ut eleifend arcu. Nam feugiat risus quis congue porttitor. Maecenas vehicula lorem ultrices ante sollicitudin, placerat sollicitudin dolor fermentum. Aliquam arcu turpis, faucibus vel placerat a, molestie vel lectus. Sed condimentum euismod tincidunt. Mauris odio tortor, luctus id eleifend vitae, aliquet ut libero. Vestibulum vitae placerat turpis. Duis nec facilisis eros. Morbi ipsum arcu, tempus ac massa nec, mollis aliquet lacus.
Phasellus maximus eros quis massa maximus, et mattis tellus cursus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras id lacus interdum, cursus diam ut, posuere purus. Duis non vestibulum nulla, vitae egestas elit. Phasellus venenatis libero in nunc lobortis tempor in vel orci. Praesent varius lacus eleifend, pretium lectus ut, pulvinar arcu. Nunc ornare dolor velit, id pulvinar urna semper eget. Aenean finibus dui vitae dolor ullamcorper finibus. Cras consequat viverra tellus, a accumsan sem viverra sed. Nulla felis tortor, laoreet non tincidunt elementum, tempus ac risus. Sed nibh nisl, ultrices vel iaculis in, fringilla at ipsum. Curabitur metus ligula, tincidunt non arcu eget, ultricies pellentesque ligula. Duis id est posuere, molestie urna non, gravida tortor. Praesent lacinia erat ac diam sagittis, quis faucibus nunc blandit.
Fusce aliquet tincidunt turpis, ut consequat metus consectetur at. Nunc volutpat semper enim, ut finibus orci luctus in. Mauris pharetra consectetur arcu sed pulvinar. Sed cursus fermentum velit, mattis varius ante commodo ac. Fusce erat mauris, sagittis quis eros vitae, consectetur venenatis nibh. Fusce porttitor tortor lectus, at efficitur diam dictum et. Quisque et suscipit sem. Mauris vulputate orci tellus, non efficitur eros blandit ut. Donec eget hendrerit elit.

如果您必须过渡元素的高度,则可以通过使用容器作为缓冲区来抵消尺寸更改的效果。

var lastScrollY = 0;
var ticking = false;
window.addEventListener('scroll', function(e) {
	lastScrollY = window.scrollY;
	if ( ! ticking ) {
		window.requestAnimationFrame(function() {
			console.log( lastScrollY );
			if ( lastScrollY > 0 ) {
				document.body.classList.add('stuck');
			} else {
				document.body.classList.remove('stuck');
			}
			ticking = false;
		});
		ticking = true;
	}
} );
body {
	margin: 0;
}
.wrapoffset { /* Make this element sticky instead */
  height: 80px;
  position: sticky;
  top: 0;
  width: 100%;
}
.wrap {
	background: #666;
	text-align: center;
  width: 100%;
}
.block {
  height: 80px;
	width: 80px;
	background: red;
	display: block;
	transition: 0.5s;
}
.stuck .block {
	height: 40px;
}
<div class="wrapoffset"> <!-- new element -->
  <div class="wrap">
    <span class="block"></span>
  </div>
</div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ac lorem a metus tincidunt eleifend id in odio. Nam malesuada hendrerit tristique. Pellentesque id ornare elit, ac lobortis metus. Sed iaculis et nisi et consectetur. Proin pellentesque metus mi, quis fringilla mauris pulvinar et. Vivamus pharetra elit ligula, eu consectetur magna consequat nec. Donec sed enim sit amet augue malesuada varius id a libero. Nullam nec ante id justo elementum congue quis in purus. Integer finibus cursus volutpat. Donec non laoreet ipsum.
Maecenas id venenatis velit, eu feugiat dolor. Vestibulum malesuada erat ut turpis mattis vehicula. Vestibulum sem leo, cursus quis lacinia eu, tincidunt eu velit. Nulla odio elit, tristique vel bibendum vitae, placerat nec eros. Proin auctor id leo sed rutrum. Proin convallis erat sit amet neque aliquam vestibulum. Ut sodales vel nisl eu imperdiet.
Donec a porttitor dui, vitae ullamcorper nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam non elit eu elit blandit hendrerit id ut eros. Duis sagittis elementum ligula eu venenatis. Aenean nunc mauris, dignissim ut venenatis ac, pharetra eget magna. Curabitur elementum enim sed pharetra rhoncus. Praesent sodales at ex at consectetur. Curabitur sed dictum mi, ut eleifend arcu. Nam feugiat risus quis congue porttitor. Maecenas vehicula lorem ultrices ante sollicitudin, placerat sollicitudin dolor fermentum. Aliquam arcu turpis, faucibus vel placerat a, molestie vel lectus. Sed condimentum euismod tincidunt. Mauris odio tortor, luctus id eleifend vitae, aliquet ut libero. Vestibulum vitae placerat turpis. Duis nec facilisis eros. Morbi ipsum arcu, tempus ac massa nec, mollis aliquet lacus.
Phasellus maximus eros quis massa maximus, et mattis tellus cursus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras id lacus interdum, cursus diam ut, posuere purus. Duis non vestibulum nulla, vitae egestas elit. Phasellus venenatis libero in nunc lobortis tempor in vel orci. Praesent varius lacus eleifend, pretium lectus ut, pulvinar arcu. Nunc ornare dolor velit, id pulvinar urna semper eget. Aenean finibus dui vitae dolor ullamcorper finibus. Cras consequat viverra tellus, a accumsan sem viverra sed. Nulla felis tortor, laoreet non tincidunt elementum, tempus ac risus. Sed nibh nisl, ultrices vel iaculis in, fringilla at ipsum. Curabitur metus ligula, tincidunt non arcu eget, ultricies pellentesque ligula. Duis id est posuere, molestie urna non, gravida tortor. Praesent lacinia erat ac diam sagittis, quis faucibus nunc blandit.
Fusce aliquet tincidunt turpis, ut consequat metus consectetur at. Nunc volutpat semper enim, ut finibus orci luctus in. Mauris pharetra consectetur arcu sed pulvinar. Sed cursus fermentum velit, mattis varius ante commodo ac. Fusce erat mauris, sagittis quis eros vitae, consectetur venenatis nibh. Fusce porttitor tortor lectus, at efficitur diam dictum et. Quisque et suscipit sem. Mauris vulputate orci tellus, non efficitur eros blandit ut. Donec eget hendrerit elit.

如果您想更优化性能,则可以考虑使用polyfill的IntersectionObserver而不是在滚动上聆听事件。

最新更新