你可以按照自然的方式来使用display,但是你需要限制浏览器来使它工作,使用JavaScript或者像其他人建议的在一个标签内嵌套另一个标签的花式技巧。我不喜欢内部标签,因为它进一步复杂了CSS和尺寸,所以这里提供JavaScript解决方案:
https://jsfiddle.net/b9chris/hweyecu4/17/
以一个类似于盒子的形状开始:
<div id="box" class="hidden">Lorem</div>
一个隐藏的框。
div.hidden {
display: none;
}
#box {
transition: opacity 1s;
}
我们将使用在相关问答中发现的技巧,检查offsetHeight以立即限制浏览器:
https://dev59.com/hWgu5IYBdhLWcg3wt5Lt#16575811
首先,一个正式化上述技巧的库:
$.fn.noTrnsn = function () {
return this.each(function (i, tag) {
tag.style.transition = 'none';
});
};
$.fn.resumeTrnsn = function () {
return this.each(function (i, tag) {
tag.offsetHeight;
tag.style.transition = null;
});
};
接下来,我们将使用它来显示一个框,并淡入:
$('#button').on('click', function() {
var tag = $('#box');
if (tag.hasClass('hidden'))
tag.noTrnsn().removeClass('hidden')
.css({ opacity: 0 })
.resumeTrnsn().css({ opacity: 1 });
else
tag.css({ opacity: 0 });
});
这段代码实现了盒子的淡入淡出效果。因此,
.noTrnsn()
关闭了过渡效果,然后我们移除了
hidden
类,将
display
从
none
翻转到其默认状态,即
block
。然后,我们将不透明度设置为0,以准备淡入。现在,我们已经做好了准备工作,使用
.resumeTrnsn()
重新开启过渡效果。最后,通过将不透明度设置为1来启动过渡效果。
如果没有库文件,更改显示和不透明度都会导致我们得到不良结果。如果我们简单地删除库调用,就根本没有过渡效果。
请注意,上述代码在淡出动画结束时并未再次将显示设置为none。我们可以使用更高级的方法。让我们尝试一种从0淡入并增加高度的方式。
华丽!
https://jsfiddle.net/b9chris/hweyecu4/22/
#box {
transition: height 1s, opacity 1s;
}
我们现在正在过渡高度和不透明度。请注意,我们没有设置高度,这意味着它是默认值
auto
。传统上,这不能过渡-从自动到像0这样的像素值移动将不会有任何过渡效果。我们将使用库和另一个库方法来解决这个问题。
$.fn.wait = function (time, fn) {
if (time)
this.delay(time);
if (!fn)
return this;
var _this = this;
return this.queue(function (n) {
fn.call(_this);
n();
});
};
这是一个方便的方法,让我们参与jQuery现有的fx/animation队列,而不需要任何在jQuery 3.x中现已排除的动画框架。我不会解释jQuery的工作原理,但可以说,jQuery提供的
.queue()
和
.stop()
管道帮助我们防止动画相互干扰。让我们动画化下滑效果。
$('#button').on('click', function() {
var tag = $('#box');
if (tag.hasClass('hidden')) {
tag.stop().noTrnsn().removeClass('hidden').css({
opacity: 0, height: 'auto'
});
var h = tag.height();
tag.css({ height: 0 }).resumeTrnsn()
.css({ opacity: 1, height: h })
.wait(1000, function() {
tag.css({ height: 'auto' });
});
} else {
var h = tag.noTrnsn().height();
tag.stop().css({ height: h })
.resumeTrnsn()
.css({ opacity: 0, height: 0 })
.wait(1000, function() {
tag.addClass('hidden');
});
}
});
这段代码首先通过检查其类别来确定
#box
是否处于隐藏状态。但是,它使用
wait()
库调用实现了更多功能,在滑动/淡出动画的末尾添加了
hidden
类,如果实际上处于隐藏状态,则会找到它 - 这是上面更简单的示例无法做到的。这也使得元素的显示/隐藏可以反复进行,这在以前的示例中是一个错误,因为隐藏类从未被恢复。
您还可以看到在
.noTrnsn()
之后调用CSS和类更改,以通常设置动画阶段,包括测量,例如测量
#box
的最终高度而不向用户显示它,然后调用
.resumeTrnsn()
,并从完全设置的阶段将其动画化到其目标CSS值。
旧答案
https://jsfiddle.net/b9chris/hweyecu4/1/
您可以使用以下代码使其在单击时进行转换:
function toggleTransition() {
var el = $("div.box1");
if (el.length) {
el[0].className = "box";
el.stop().css({maxWidth: 10000}).animate({maxWidth: 10001}, 2000, function() {
el[0].className = "box hidden";
});
} else {
el = $("div.box");
el[0].className = "box";
el.stop().css({maxWidth: 10001}).animate({maxWidth: 10000}, 50, function() {
el[0].className = "box box1";
});
}
return el;
}
someTag.click(toggleTransition);
CSS就是你猜到的那样:
.hidden {
display: none;
}
.box {
width: 100px;
height: 100px;
background-color: blue;
color: yellow;
font-size: 18px;
left: 20px;
top: 20px;
position: absolute;
-webkit-transform-origin: 0 50%;
transform-origin: 0 50%;
-webkit-transform: scale(.2);
transform: scale(.2);
-webkit-transition: transform 2s;
transition: transform 2s;
}
.box1{
-webkit-transform: scale(1);
transform: scale(1);
}
关键在于限制显示属性。通过移除隐藏类,然后等待50毫秒,
然后通过添加的类开始过渡,我们使其出现并像我们想要的那样扩展,而不是它只是在屏幕上闪烁而没有任何动画。反向操作类似,只是在应用隐藏之前等待动画结束。
注意:我在这里滥用了.animate(maxWidth)
,以避免 setTimeout
竞争条件。当您或其他人不知道它的代码时,setTimeout
很容易引入隐藏的错误。 .animate()
可以轻松使用.stop()
终止。我只是用它来在标准fx队列上放置50毫秒或2000毫秒的延迟,其他构建在其上的编码人员可以轻松找到/解决它。
z-index:0
的内容时才行。 - DanManvisibility: hidden
,除非你希望屏幕阅读器读取它(而典型的浏览器不会)。它仅定义元素的可见性(就像说opacity: 0
一样),它仍然是可选、可点击和以前的任何状态;它只是不可见。 - Forest Katschpointer-events
,因此并不总是可行。 - Steven Pribilinskiy