我正在建立一个网站,当您滚动浏览页面的不同部分时,标题会更改颜色,它通过显示/隐藏不同颜色的标题的不同层,跟踪页面的顶部/底部以使其对齐来实现此目的滚动时。在Chrome,Firefox等系统中正常运行。
但是,Edge非常令人沮丧,对于基于滚动的动画来说,它像地狱般令人毛骨悚然。我之前已经遇到过很多次此问题,但没有找到解决方案,也无法在线找到有关该问题的很多信息。
我创建了一个精简的测试用例。只是标头元素在Y轴上平移的量与scrollTop相等,因此它与页面顶部保持对齐。
尽管我的动画在固定位置元素中为不同的图层设置了动画,但此测试用例却演示了完全相同的故障。
scrollTop值似乎在波动,或者应用样式存在一些延迟。
此问题也影响基于滚动的视差,使其在滚动时快速上下抖动。
当不使用requestAnimationFrame循环时,故障仍然会发生。
测试用例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<style type="text/css">
body {
margin: 0;
padding-bottom: 4000px;
}
#header {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100px;
border: 2px solid #444444;
}
* {
box-sizing: border-box;
}
</style>
</head>
<body>
<header id="header">
Test Header
</header>
<script type="text/javascript">
var header = document.getElementById('header'),
scrollTop = 0,
loopTimeout = null;
function frame() {
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
header.style.transform = 'translateY(' + scrollTop + 'px)';
if (loopTimeout) {
requestFrame();
}
}
function requestFrame() {
window.requestAnimationFrame(frame);
}
function endLoop() {
clearTimeout(loopTimeout);
loopTimeout = null;
}
function startLoop() {
loopTimeout = setTimeout(endLoop, 500);
}
function onWindowScroll() {
let frame = loopTimeout;
endLoop();
startLoop();
if ( ! frame) {
requestFrame();
}
}
window.addEventListener('scroll', onWindowScroll);
</script>
</body>
</html>
答案 0 :(得分:0)
除了控制滚动行为外,我找不到其他解决方法。这真的很讨厌,肮脏,并且可以考虑其他任何负面描述词,但是嘿,它确实可行。不过,我希望听到更好的解决方案。
解决方案:
applyIEFixes() {
let container,
scrollTop;
// IE 11 needs documentElement as container
if (this.app.IEVersion <= 11) {
container = document.documentElement;
scrollTop = document.documentElement.scrollTop;
}
// Edge needs body, however
else {
container = document.body;
scrollTop = document.body.scrollTop;
}
let onWheel = event => {
event.preventDefault();
scrollTop += event.deltaY;
if (scrollTop < 0) {
scrollTop = 0;
}
if (scrollTop > this.maxScrollTop) {
scrollTop = this.maxScrollTop;
}
// So we can have some sort of smooth scrolling, still
TweenLite.to(container, 0.2, {
scrollTop,
ease: Power2.easeOut
});
};
let onScroll = () => {
scrollTop = container.scrollTop;
};
container.addEventListener('wheel', onWheel, { passive: false, capture: true });
// 300ms after last scroll, update the current scrollTop value
window.addEventListener('scroll', Helpers.delayedFunction(300, onScroll), { passive: false });
}