Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

临时无视CSS3的transition直接设置样式

  如果元素设置了transition,那么用JavaScript来操作相应样式时就会有过度效果。可是有时候咱不想要这个效果,只想直接设置怎么办?这时候很容易想到暂时移除transition样式的做法吧?但是JavaScript操作元素样式还有处理机制的问题,不是那么简单的。
  来试试对一个没有设置transition的元素加上其它样式后再添加transition的情况 <span style="font:32px/48px 微软雅黑;">次碳酸钴</span>
<script>
onload=function(){
  var span=document.querySelector("span");
  span.style.color="red"; //设置成红色
  span.style.transition="color 500ms"; //添加transition
};
</script>
  执行这个程序会发现页面打开时transition效果依然存在,这就是因为处理机制的问题。JavaScript是单线程的,它使用消息机制,我们给元素赋予样式其实只是个赋值而已,CSS引擎并没有立即处理这些赋予的值(没有触发RecalculateStyle)。只有等到JavaScript把当前消息处理完毕或执行到特殊的代码时才有可能去处理CSS。上面的代码在同一个消息处理中设置的两个样式color和transition,而且也没有特定代码来触发RecalculateStyle,因此它们会被放入下一次触发RecalculateStyle时一起处理。这就造成了上面transition依然对color=red生效的原因。我们要解决的根本问题就是在设置transition之前把color=red处理好。
  根据处理机制不同这里有两种思路,先来看第一种思路,把设置transition的工作放入其它消息中处理,像下面这样 <span style="font:32px/48px 微软雅黑;">次碳酸钴</span>
<script>
onload=function(){
  var span=document.querySelector("span");
  span.style.color="red"; //设置成红色
  //在消息队列中添加新消息
  setTimeout(function(){
    span.style.transition="color 500ms"; //添加transition
  });
};
</script>
  这个解决了Chrome和IE中的问题,但是在Firefox中的状况是时好时坏的,这可能和Firefox对CSS渲染的一些优化细节有关。Firefox在一个消息处理完成后未必会立即处理CSS,我们需要想办法让它在消息结束时处理CSS。这很容易想到requestAnimationFrame吧?这个函数的功能类似setTimeout,而且还有触发CSS渲染的功能。上面的代码中color=red是在onload事件中执行的,它执行完未必会立即处理渲染,于是我们把它放入一个requestAnimationFrame中执行。
<span style="font:32px/48px 微软雅黑;">次碳酸钴</span>
<script>
var RAF=window.mozRequestAnimationFrame||requestAnimationFrame;
onload=function(){
  var span=document.querySelector("span");
  //添加一个RAF消息
  RAF(function(){
    span.style.color="red"; //设置成红色
    //再添加一个RAF消息(这里如果用setTimeout会不兼容IE)
    RAF(function(){
      span.style.transition="color 500ms"; //设置transition
    });
  });
};
</script>
  这样,IE、Chrome、Firefox,就全都能兼容了。是不是觉得这个方法很麻烦呢?现在来看看另一种思路。如果有什么特殊代码可以强制处理CSS就不需要这么麻烦的嵌套一大堆消息了吧。这样的方法当然有,比如alert。当执行alert时候会弹出对话框,这时我们看到的界面也是把alert之前的CSS都处理完的。也就是说,alert本身有处理CSS的功能。这里我就不演示它了,因为这货显然不实用。除了alert之外有没有什么实用的方法呢?有,还有一个getComputedStyle!这个方法是获取一个元素上计算后的样式,而计算样式实际上就是RecalculateStyle的工作。所以要实用getComputedStyle必然要触发RecalculateStyle,这样CSS就被处理了。这正是我们要的! <span style="font:32px/48px 微软雅黑;">次碳酸钴</span>
<script>
onload=function(){
  var span=document.querySelector("span");
  span.style.color="red"; //设置成红色
  getComputedStyle(span).color //强制计算color样式
  span.style.transition="color 500ms"; //设置transition
};
</script>
  这样就可以简单的兼容上所有浏览器了。注意getComputedStyle返回一个满是getter属性的对象,所以需要访问它的color属性才会触发color计算。
网名:
54.162.218.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^