css不能在display:none和display:block之间进行动画,并且也不能在height:0和height:auto之间进行动画。这里我研究了一下在display:none和display:block之间进行动画的解决方案,记录下来供以后开发时参考,相信对其他人也有用。
我的理解是这样的:由于display:none会引起页面的重绘事件,所以它是一个异步的延时事件,所以浏览器其实会先解析animate的代码,然后再执行display:none。
这样就引发了一个问题:如果我们要设置类似淡入淡出的效果怎么办?就是让元素在消失/出现的同时产生动画怎么办?这里我研究了2个解决方案。
不利用display:none,而是利用它的替代方式:
opacity: 0;visibility: hidden;
但是这样会占据空间。如果不想占据空间的话,只能使用绝对定位,把元素独立出去。这个时候会有一个层叠问题,所以需要搭配z-index控制层叠关系使它出现或者消失。
示例如下:
//自身css效果
.animate {
position: absolute;
top: 0;
left: 0;
transition: 1s;
opacity: 0;
visibility: hidden;
z-index: 0;
}
//出现时的效果
.cur {
opacity: 1;
visibility: visible;
z-index: 10;
}jquery里面也有淡入淡出的方法,它是怎么实现的呢?通过查资料可以知道,它是通过deferred对象通过延时display: none来实现的。好处是能够适用于出现时占据空间,消失时又不占据空间的情况。实例如下:
//css
.div {
display: none;
}
.div-animate1 {
display: block;
visibility: hidden;
opacity: 0;
transform: translate3d(100px, 0, 0);
transition: 1s;
}
.div-animate2 {
visibility: visible;
opacity: 1;
transform: translate3d(0, 0, 0);
}
//js
function divAnimate1($div, divClass1, divClass2) {
$div.addClass(divClass1);
setTimeout(function(){
$div.addClass(divClass2);
});
}
function divAnimate2($div, divClass1, divClass2) {
$div.removeClass(divClass2);
setTimeout(function(){
$div.removeClass(divClass1);
}, 1000); //1s是动画时间。
}我还试过用transitionend事件,window.requestanimationframe来实现,但是都或多或少的有副作用。
另外总结一下:
如果消失前后都需要占据空间,则用visiblity。
如果消失前后都不需要占据空间,则用绝对定位和visiblity。
如果消失前需要占据空间但是消失后不需要占据空间,则用timeout和visiblity。
DISPLAY:NONE的元素如何触发过渡动画?
display:none的元素更改为display:block为何不可以和其他属性修改一样触发动画呢?
这是因为display属性刚开始是none,所以还没有创建,改为block之后需要等待js渲染队列更新
但是transition属性在一开始就有了,所以transform改变元素的时候并没有触发动画
解决方法:让元素获取dom.offsetHeight,触发js渲染队列更新,让元素先展示出来。
<!DOCTYPE html>
<html>
<head>
<title>测试</title>
<style type="text/css">
html, body, div, span,
h1, h2, h3, h4, h5, h6, p
a, img, ol, ul, li
{
margin:0;padding:0;border:0;outline:0;
}
ul, li{
list-style-type: none;
}
.father{
border: 1px solid black;
height: 300px;
width: 1000px;
}
.one{
background-color: red;
height: 300px;
width: 200px;
display: none;
transition: 1s ease;
}
</style>
</head>
<body>
<div class="father">
<div class="one"></div>
<button type="button" onclick="change()">测试</button>
</div>
<script>
function change(){
var one = document.getElementsByClassName('one')[0];
one.style.display='block';
// 区别在于有没有获取one.offsetHeight
console.log(one.offsetHeight);
one.style.transform='translateX(200px)';
}
</script>
</body>
</html>用opacity实现淡入淡出的效果。噢!good!一切正常
<!DOCTYPE html>
<html>
<meta charset="uft-8">
<head>
<style>
.div1{
background: red;
}
.div2 {
width:100px;
height:100px;
background:blue;
transition:opacity 2s;
-moz-transition:opacity 2s; /* Firefox 4 */
-webkit-transition:opacity 2s; /* Safari and Chrome */
-o-transition:opacity 2s; /* Opera */
opacity: 0;
}
.div1:hover .div2 {
opacity:1;
}
</style>
</head>
<body>
<div class="div1">
<p>请移动到红色div上</p>
<div class="div2"></div>
</div>
</body>
</html>或者用animation,在keyframe中写也一样。这里就不写出代码了
但是难免我们会遇到这样的需求,也一定会遇到: 我们都知道opacity:0的时候,其实他还是占页面空间的,他会遮挡到他下面的层(不是视觉上)。而且绑定在他上面的一些onclick事件之类的,也同样会发生。 这时候我们想在opacity:0的时候,把他隐藏掉,用display: none。 好,那我们稍微在css中加几句,变成
.div1{
background: red;
}
.div2 {
width:100px;
height:100px;
background:blue;
transition:opacity 2s;
-moz-transition:opacity 2s; /* Firefox 4 */
-webkit-transition:opacity 2s; /* Safari and Chrome */
-o-transition:opacity 2s; /* Opera */
opacity: 0;
display: none;
}
.div1:hover .div2 {
opacity:1;
display:block
}打开浏览器看一下效果先。 我擦。。。。淡入淡出的效果全没了怎么回事。。。这简直是破坏性的作用,这也是之前做动画过程中遇到的大坑
聪明的码农们当然有办法来解决这种情况。 大家都知道visibility的效果其实跟 display 在一定程度上相似, 当然是一定程度上。 那为什么说只是一定程度上相似呢,因为它仍然是占空间的,那么这时候看官一定会说,这么用跟opacity压根没区别呀
但聪明的码农们一定又想到,这时候,他是不会遮挡到下面的层的,也就是说 他跟opacity这样的存在不同,onclick等事件是不会发生的。
我们来说下visibility, 常用到的是visible和 hidden 两个值。但也可以是数值, 等于0时相当于hidden,而只要大于0时,visibility就为visible。那我们利用这点。
.div1{
background: red;
}
.div2 {
width:100px;
height:100px;
background:blue;
transition:all 2s;
-moz-transition:all 2s; /* Firefox 4 */
-webkit-transition:all 2s; /* Safari and Chrome */
-o-transition:all 2s; /* Opera */
visibility: hidden
}
.div1:hover .div2 {
visibility: visible
}浏览一下,会发现,这时候是会有延时隐藏的效果的。很好,又发现新东西了
那渐变的效果怎么办。。。。
聪明的码农们又想起了opacity 。。。结合起来用会怎么用呢
.div1{
background: red;
}
.div2 {
width:100px;
height:100px;
background:blue;
transition:all 2s;
-moz-transition:all 2s; /* Firefox 4 */
-webkit-transition:all 2s; /* Safari and Chrome */
-o-transition:all 2s; /* Opera */
visibility: hidden;
opacity: 0
}
.div1:hover .div2 {
visibility: visible;
opacity: 1
}浏览下先。。。。!!!!一切正常了
其实,visibility会在opacity生效后再应用。比如隐藏时,先opacity变为0,再应用了visibility:hidden 这时候就隐藏起来了,相关的事件也不会发生。 看来display:none这时候被抛弃了啊
当然,有人会说visibility:hidden始终是占着页面空间的,display能够减少页面的repaint,还是要用display:none怎么做呢
聪明的码农又想到了: 先把display变成block 然后延迟transition动画的执行
当然啦 这就需要用到JS了
以上就是css3 动画与display:none冲突的解决方法!
如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛