Safari忽略关键帧动画的内联样式



在Safari(桌面和iOS(中仅使用结束帧使用CSStransform设置@keyframes,然后以编程方式更新起始transform位置(通过JS内联(时,Safari似乎会继续从初始位置执行动画(即使用样式表中的初始转换值(,而不是使用内联样式。

简而言之,Safari关键帧动画似乎不会更新以反映以编程方式添加的内联样式的任何更改

下面的代码段(简化的测试用例(适用于Firefox和Chrome,但Safari只是将动画设置到0的位置。我的问题是,是否有解决办法?这是苹果公司对规范的有意表示吗?关键帧动画是否应该忽略编程内联样式?我无法想象他们会这么做。

我尝试过克隆和替换元素,但没有成功。我还测试了onLoad中包含的内联样式,这个在Safari中运行了,所以这个bug似乎只有在以编程方式添加样式时才会出现。

我很感激我可以完全使用JS和requestAnimationFrame制作动画,如果以上操作失败,这是我的后备解决方案。(同样,一个很好的解决方案是使用Web Animation API,它似乎正是为此目的而设计的。但对它的支持是不完整的,所以现在不支持(。我真正感兴趣的是上述错误的解决方案,而不是其他建议。

(顺便说一句,<marquee>标签仍然可以作为跨浏览器解决方案…*不寒而栗*(

// Get slides
let marquee = document.querySelector('.mock-marquee__content');
// Transform slides for initial offset
marquee.style.transform = `translate(-${marquee.clientWidth}px, 0)`;
.mock-marquee {
overflow: hidden;
display: flex;
}
.mock-marquee__content {
white-space: nowrap;
display: flex;
animation: marquee 5s linear infinite;
}
.mock-marquee__content__slide {
display: block;
}
.mock-marquee__content__slide:not(:first-child) {
margin-left: 100px;
}
.mock-marquee__content:hover {
animation-play-state: paused;
}
@keyframes marquee {
from {
transform: translate(100vw, 0);
}
}
<div class="mock-marquee">
<div class="mock-marquee__content">
<span class="mock-marquee__content__slide">Hello</span>
<span class="mock-marquee__content__slide">world</span>
<span class="mock-marquee__content__slide">Foo</span>
<span class="mock-marquee__content__slide">Bar</span>
<span class="mock-marquee__content__slide">Bat</span>
<span class="mock-marquee__content__slide">Another one</span>
<span class="mock-marquee__content__slide">And another! Wowz</span>
</div>
</div>

解决了它!解决方案只是在删除/添加节点时使用setTimeout强制执行队列。像这样:

window.addEventListener('load', () => {
let marqueeWrapper = marquee.parentNode;
// Remove marquee
marquee.remove();
// Re-add, with forced queuing
setTimeout(() => {
marqueeWrapper.append(marquee);
}, 0)
})

这迫使Safari完全重新渲染节点,并似乎修复了问题

最新更新