您现在的位置: 365建站网 > 365文章 > css3 动画与display:none冲突的解决方法

css3 动画与display:none冲突的解决方法

文章来源:365jz.com     点击数:2192    更新时间:2021-07-24 17:06   参与评论

css不能在display:none和display:block之间进行动画,并且也不能在height:0和height:auto之间进行动画。这里我研究了一下在display:none和display:block之间进行动画的解决方案,记录下来供以后开发时参考,相信对其他人也有用。

我的理解是这样的:由于display:none会引起页面的重绘事件,所以它是一个异步的延时事件,所以浏览器其实会先解析animate的代码,然后再执行display:none。

这样就引发了一个问题:如果我们要设置类似淡入淡出的效果怎么办?就是让元素在消失/出现的同时产生动画怎么办?这里我研究了2个解决方案。

利用绝对定位和visiblity

不利用display:none,而是利用它的替代方式:

</>code

  1. opacity: 0;visibility: hidden;

但是这样会占据空间。如果不想占据空间的话,只能使用绝对定位,把元素独立出去。这个时候会有一个层叠问题,所以需要搭配z-index控制层叠关系使它出现或者消失。

示例如下:

</>code

  1. //自身css效果
  2. .animate {
  3.     position: absolute;
  4.     top: 0;
  5.     left: 0;
  6.     transition: 1s;
  7.     opacity: 0;
  8.     visibility: hidden;
  9.     z-index: 0;
  10. }
  11. //出现时的效果
  12. .cur {
  13.     opacity: 1;
  14.     visibility: visible;
  15.     z-index: 10;
  16. }

利用timeout

jquery里面也有淡入淡出的方法,它是怎么实现的呢?通过查资料可以知道,它是通过deferred对象通过延时display: none来实现的。好处是能够适用于出现时占据空间,消失时又不占据空间的情况。实例如下:

</>code

  1. //css
  2. .div {
  3.     display: none;
  4. }
  5. .div-animate1 {
  6.     display: block;
  7.     visibility: hidden;
  8.     opacity: 0;
  9.     transform: translate3d(100px, 0, 0);
  10.     transition: 1s;
  11. }
  12. .div-animate2 {
  13.     visibility: visible;
  14.     opacity: 1;
  15.     transform: translate3d(0, 0, 0);
  16. }
  17. //js
  18. function divAnimate1($div, divClass1, divClass2) {
  19.     $div.addClass(divClass1);
  20.     setTimeout(function(){
  21.         $div.addClass(divClass2);
  22.     });
  23. }
  24. function divAnimate2($div, divClass1, divClass2) {
  25.     $div.removeClass(divClass2);
  26.     setTimeout(function(){
  27.         $div.removeClass(divClass1);
  28.     }, 1000); //1s是动画时间。
  29. }

其它

我还试过用transitionend事件,window.requestanimationframe来实现,但是都或多或少的有副作用。

另外总结一下:

  1. 如果消失前后都需要占据空间,则用visiblity。

  2. 如果消失前后都不需要占据空间,则用绝对定位和visiblity。

  3. 如果消失前需要占据空间但是消失后不需要占据空间,则用timeout和visiblity。


DISPLAY:NONE的元素如何触发过渡动画?

display:none的元素更改为display:block为何不可以和其他属性修改一样触发动画呢?

这是因为display属性刚开始是none,所以还没有创建,改为block之后需要等待js渲染队列更新

但是transition属性在一开始就有了,所以transform改变元素的时候并没有触发动画

解决方法:让元素获取dom.offsetHeight,触发js渲染队列更新,让元素先展示出来。

</>code

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.   <title>测试</title>
  5.   <style type="text/css">
  6.   html, body, div, span,
  7.   h1, h2, h3, h4, h5, h6, p
  8.   a, img, ol, ul, li
  9.   {
  10.       margin:0;padding:0;border:0;outline:0;
  11.   }
  12.   ul, li{
  13.   list-style-type: none;
  14.   }
  15.   .father{
  16.   border: 1px solid black;
  17.   height: 300px;
  18.   width: 1000px;
  19.   }
  20.   .one{
  21.   background-color: red;
  22.   height: 300px;
  23.   width: 200px;
  24.   display: none;
  25.   transition: 1s ease;
  26.   }
  27.    </style>
  28. </head>
  29. <body>
  30. <div class="father">
  31. <div class="one"></div>
  32. <button type="button" onclick="change()">测试</button>
  33. </div>
  34. <script>
  35. function change(){
  36. var one = document.getElementsByClassName('one')[0];
  37. one.style.display='block';
  38. // 区别在于有没有获取one.offsetHeight
  39. console.log(one.offsetHeight);
  40. one.style.transform='translateX(200px)';
  41. }
  42. </script>
  43. </body>
  44. </html>

用opacity实现淡入淡出的效果。噢!good!一切正常


</>code

  1. <!DOCTYPE html>
  2. <html>
  3. <meta charset="uft-8">
  4. <head>
  5. <style>
  6. .div1{
  7.      background: red;
  8. }
  9. .div2 {
  10.      width:100px;
  11.      height:100px;
  12.      background:blue;
  13.      transition:opacity 2s;
  14.      -moz-transition:opacity 2s; /* Firefox 4 */
  15.      -webkit-transition:opacity 2s; /* Safari and Chrome */
  16.      -o-transition:opacity 2s; /* Opera */
  17.      opacity: 0;
  18. }
  19. .div1:hover .div2 {
  20.      opacity:1;
  21. }
  22. </style>
  23. </head>
  24. <body>
  25.      <div class="div1">
  26.      <p>请移动到红色div上</p>
  27.      <div class="div2"></div>
  28. </div>
  29. </body>
  30. </html>


或者用animation,在keyframe中写也一样。这里就不写出代码了
但是难免我们会遇到这样的需求,也一定会遇到: 我们都知道opacity:0的时候,其实他还是占页面空间的,他会遮挡到他下面的层(不是视觉上)。而且绑定在他上面的一些onclick事件之类的,也同样会发生。 这时候我们想在opacity:0的时候,把他隐藏掉,用display: none。 好,那我们稍微在css中加几句,变成

</>code

  1. .div1{
  2.      background: red;
  3. }
  4. .div2 {
  5.      width:100px;
  6.      height:100px;
  7.      background:blue;
  8.      transition:opacity 2s;
  9.      -moz-transition:opacity 2s; /* Firefox 4 */
  10.      -webkit-transition:opacity 2s; /* Safari and Chrome */
  11.      -o-transition:opacity 2s; /* Opera */
  12.      opacity: 0;
  13.      display: none;
  14. }
  15. .div1:hover .div2 {
  16.      opacity:1;
  17.      display:block
  18. }

打开浏览器看一下效果先。 我擦。。。。淡入淡出的效果全没了怎么回事。。。这简直是破坏性的作用,这也是之前做动画过程中遇到的大坑

聪明的码农们当然有办法来解决这种情况。 大家都知道visibility的效果其实跟 display 在一定程度上相似, 当然是一定程度上。 那为什么说只是一定程度上相似呢,因为它仍然是占空间的,那么这时候看官一定会说,这么用跟opacity压根没区别呀

但聪明的码农们一定又想到,这时候,他是不会遮挡到下面的层的,也就是说 他跟opacity这样的存在不同,onclick等事件是不会发生的。

我们来说下visibility, 常用到的是visible和 hidden 两个值。但也可以是数值, 等于0时相当于hidden,而只要大于0时,visibility就为visible。那我们利用这点。

</>code

  1. .div1{
  2.      background: red;
  3. }
  4. .div2 {
  5.      width:100px;
  6.      height:100px;
  7.      background:blue;
  8.      transition:all 2s;
  9.      -moz-transition:all 2s; /* Firefox 4 */
  10.      -webkit-transition:all 2s; /* Safari and Chrome */
  11.      -o-transition:all 2s; /* Opera */
  12.      visibility: hidden
  13. }
  14. .div1:hover .div2 {
  15.      visibility: visible
  16. }


浏览一下,会发现,这时候是会有延时隐藏的效果的。很好,又发现新东西了


那渐变的效果怎么办。。。。


聪明的码农们又想起了opacity 。。。结合起来用会怎么用呢

</>code

  1. .div1{
  2.      background: red;
  3. }
  4. .div2 {
  5.      width:100px;
  6.      height:100px;
  7.      background:blue;
  8.      transition:all 2s;
  9.      -moz-transition:all 2s; /* Firefox 4 */
  10.      -webkit-transition:all 2s; /* Safari and Chrome */
  11.      -o-transition:all 2s; /* Opera */
  12.      visibility: hidden;
  13.      opacity: 0
  14. }
  15. .div1:hover .div2 {
  16.      visibility: visible;
  17.      opacity: 1
  18. }


浏览下先。。。。!!!!一切正常了


其实,visibility会在opacity生效后再应用。比如隐藏时,先opacity变为0,再应用了visibility:hidden 这时候就隐藏起来了,相关的事件也不会发生。 看来display:none这时候被抛弃了啊


当然,有人会说visibility:hidden始终是占着页面空间的,display能够减少页面的repaint,还是要用display:none怎么做呢


聪明的码农又想到了: 先把display变成block 然后延迟transition动画的执行


当然啦 这就需要用到JS了


以上就是css3 动画与display:none冲突的解决方法!



如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛

发表评论 (2192人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
昵称:
最新评论
------分隔线----------------------------

快速入口

· 365软件
· 杰创官网
· 建站工具
· 网站大全

其它栏目

· 建站教程
· 365学习

业务咨询

· 技术支持
· 服务时间:9:00-18:00
365建站网二维码

Powered by 365建站网 RSS地图 HTML地图

copyright © 2013-2024 版权所有 鄂ICP备17013400号