当前位置: 首页 > 面试题库 >

干净的方法来以编程方式使用JS的CSS过渡?

彭鹭洋
2023-03-14
问题内容

顾名思义,是否有适当的方法来设置一些初始CSS属性(或类),并告诉浏览器将其转换为另一个值?

var el = document.querySelector('div'),
    st = el.style;
st.opacity = 0;
st.transition = 'opacity 2s';
st.opacity = 1;

这不会激活Chrome 29 / Firefox 23中元素的不透明度。这是因为(源):

[…]您会发现,如果同时应用两组属性,则立即应用一组属性,然后浏览器将尝试优化属性更改,而忽略您的初始属性并防止过渡。在幕后,浏览器在绘画之前先批处理属性更改,这通常会加快渲染速度,但有时可能会产生不利影响。

解决方案是在应用两组属性之间强制重绘。一个简单的方法就是通过访问DOM元素的offsetHeight属性[…]

实际上,该破解确实适用于当前的Chrome / Firefox版本。更新了代码(小提琴 -
Run打开小提琴后单击以再次运行动画):

var el = document.querySelector('div'),
    st = el.style;
st.opacity = 0;
el.offsetHeight; //force a redraw
st.transition = 'opacity 2s';
st.opacity = 1;

但是,这有点黑,据报道在某些android设备上不起作用。

建议使用,setTimeout以便浏览器有时间执行重绘,但是它也失败了,因为我们不知道重绘将花费多长时间。猜测适当的毫秒数(30-100?)以确保发生重绘就意味着牺牲性能,而不必要地闲置是希望浏览器在那短时间内表现出某种魔力。

通过测试,我发现了另一个解决方案,使用requestAnimationFrame在最新的Chrome上运行良好:

var el = document.querySelector('div'),
    st = el.style;
st.opacity = 0;
requestAnimationFrame(function() {
    st.transition = 'opacity 2s';
    st.opacity = 1;
});

我假设requestAnimationFrame等到下一次重画开始之前,然后执行回调,因此浏览器不会批处理属性更改。此处不确定,但可以在Chrome
29上正常使用。

更新: 经过进一步测试,该requestAnimationFrame方法在Firefox 23上效果不佳-
多数情况下似乎失败。

是否有合适的或推荐的(跨浏览器)方式来实现这一目标?


问题答案:

目前还没有一种干净的方法(不使用CSS动画-有关使用CSS动画的示例。有一个规范错误14617,很遗憾,自2011年提交以来就没有得到纠正。

setTimeout在Firefox中无法可靠地运行这是设计使然。

我不确定requestAnimationFrame-对原始问题的编辑说它也不可靠,但是我没有调查。(更新:看起来requestAnimationFrame至少一位Firefox核心开发人员认为是可以进行更多更改的地方,而不必一定看到先前更改的效果。)

window.getComputedStyle(elem).opacity;

请注意,仅运行getComputedStyle(elem)是不够的,因为它是惰性计算的。我相信您从getComputedStyle询问哪个属性都没有关系,重新样式仍然会发生。请注意,询问与几何相关的属性可能会导致更昂贵的回流。



 类似资料:
  • 问题内容: 我有一个DOM元素,应用了以下一些/全部效果: 我正在编写一个调整此元素大小的jQuery插件,我需要暂时禁用这些效果,以便可以平滑地调整其大小。 临时禁用这些效果(然后重新启用它们)的最优雅的方法是什么,因为它们可能是由父母应用的,也可能根本没有应用。 问题答案: 简短答案 使用此CSS: 加上这个JS(没有jQuery)… 或者这个带有jQuery的JS … …或使用您正在使用的任

  • 问题内容: 一个没有stopServer功能的RMI服务器,可以正常工作。 每当被调用异常中的stopServer()抛出时 这是堆栈跟踪 即使我使用清理服务对象,情况也一样 有人可以提出一种干净的方法来停止服务器,这还会释放端口以供重用。 问题答案: 您需要存储结果并取消导出结果。目前,您正在尝试取消导出存根。

  • 下面是: 下面是 为了简单起见,我使用了H2数据库,因为它是一个基于文件的数据库,很容易创建和测试。

  • 问题内容: 我使用并不少。 这是以下示例输出: 今天,我只需要在脚本中检索uwsgi 的 主进程 (因此我只需要15237,而不想要15293或15294)。 从今天开始,我尝试了一些……但是我想要一种 更清洁的方法 。 我还遇到了unix.com论坛中的另一种解决方案: 但是仍然有 很多管道 和 丑陋的招数 。 真的没有选择或更巧妙的技巧(也许使用 awk )来完成该任务吗? 问题答案: 与@n

  • 我有一些简单的枚举名:失败/成功的结果 我有一个函数,它什么也没有得到,但返回未来的结果, 我不喜欢我的解决方案,它看起来很凌乱,有更简单的吗? 返回 我想在这里做的是,如果返回None,那么func应该返回Future[Fail],否则调用db,这也返回一个case类的未来,并基于响应返回Fail/Success。 但我正在寻找一种超级时尚的斯卡拉方式,让它看起来不错:) 谢谢

  • 问题内容: 这是我的问题:我有一个对话框,其中包含一些用户可以更改的参数(例如,通过微调器)。每次更改这些参数之一时,我都会启动一个线程以根据新的参数值更新3D视图。如果在第一个线程正在工作时用户更改了另一个值(或通过单击微调箭头多次再次更改了相同的值),我想中止第一个线程(以及3D视图的更新)并启动一个新线程具有最新的参数值。 我该怎么做? PS:我的线程的方法中没有循环,因此检查标志不是一个选