我注意到Chrome中的视图转换和滚动恢复有一些奇怪的行为,我试图了解这些是错误还是故意的行为。我找不到任何官方信息,说明它们应该如何与滚动相结合。
我创建了一个fiddle,它模拟了一个SPA,包含两个页面:一个在页面的末尾有一个蓝色的小球,另一个在页面的顶部有一个蓝色的大球。
如果我
- 滚动到第1页的末尾
- 点击“下一步”转到第2页
- 向上滚动第2页
- 按back
Chrome将
- 立即向下滚动第2页以恢复滚动位置
- 开始一个动画的球开始在其 * 新 * 的位置(这是高于在页面上比它是当我按回)
- 然后平滑地动画到第1页
在开始动画之前,它首先恢复滚动位置,导致动画中的不连续性,IMO完全破坏了它的点。
我做错了什么,例如。我的SPA功能有什么问题吗?或者这是Chrome的一个bug,或者这是一个故意的行为?
这是代码:
let page = 0;
function render() {
let body = '';
if (page == 0) {
for (let i = 0; i < 13; i++) {
body += `<p>.</p>`;
}
body += `<div style="height: 30px; width: 30px; border-radius: 100%; background-color: blue; view-transition-name: bar"></div>`
} else {
body += `<div style="height: 300px; width: 300px; border-radius: 100%; background-color: blue; view-transition-name: bar"></div>`
for (let i = 0; i < 13; i++) {
body += `<p>.</p>`;
}
}
document.querySelector('#content').innerHTML = body;
document.querySelector('a').innerHTML = page == 0 ? 'Next' : 'Back';
}
render();
const useViewTransitions = true;
function transition() {
if (useViewTransitions) {
document.startViewTransition(render);
} else {
render();
}
}
document.querySelector('a').addEventListener("click",
async function(event) {
event.preventDefault();
if (page == 0) {
page++;
history.pushState({
page
}, '');
transition();
} else {
history.back();
}
}
);
window.addEventListener("popstate", ({
state
}) => {
page = state ? .page || 0;
transition()
})
使用以下HTML
<div style="height: 30px; width: 30px; border-radius: 100%; background-color: red"></div>
<div id="content">
</div>
<a href="#"></a>
--
我希望上面的描述是可以理解的。不幸的是,我不能发布视频,但这是我在第二页(滚动到页面顶部)之前的瞬间:
这是一个瞬间后,当它滚动我下来,然后开始动画
1条答案
按热度按时间bweufnob1#
我在一个涉及滚动的视图转换中遇到了类似的问题。我的解决方案是在转换函数的开始和结束时稍微延迟,例如。
我认为在为过渡创建快照和设置滚动位置之间存在轻微的竞争条件。