从元素中删除 类 而不影响正在进行的 css 转换
Removing classes from element without affecting css transitions in progress
好的,我有一种情况,我基本上构建了一个小的通知下拉框,当用户做某事时,它会在最后转换到 opacity: 0;
状态。
但是,因为用户可能会单击其他会再次触发此通知框的东西,所以我正在尝试想出一种方法将其重置为正常状态,而不影响任何正在进行的转换并尝试保持动画完成通过 CSS 而不是 JavaScript.
CodePen:http://codepen.io/gutterboy/pen/WoEydg
HTML:
<a href="#">Open Notify Window</a>
<div id="top_notify" class="top-notify">
<div class="container-fluid">
<div class="row">
<div class="content col-xs-12">
<div class="alert" role="alert"></div>
</div>
</div>
</div>
</div>
SCSS:
body {
text-align: center;
padding-top: 150px;
}
.top-notify {
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
.content {
text-align: center;
background-color: transparent;
transform-style: preserve-3d;
}
.alert {
display: inline-block;
transform: translateY(-100%);
min-width: 250px;
max-width: 500px;
border-top-left-radius: 0;
border-top-right-radius: 0;
&.visible {
transform: translateY(0%);
transition: 0.8s 0s, opacity 1s 3.8s;
opacity: 0;
}
}
}
JS:
$('a').on('click', function(e){
e.preventDefault();
myFunc();
});
function myFunc() {
// Set file to prepare our data
var loadUrl = "https://crossorigin.me/http://codepen.io/gutterboy/pen/ObjExz.html";
// Run request
getAjaxData(loadUrl, null, 'POST', 'html')
.done(function(response) {
var alert_el = $('#top_notify').find('.alert');
// Update msg in alert box
alert_el.text(response);
alert_el.addClass('alert-success');
// Slide in alert box
alert_el.addClass('visible');
})
.fail(function() {
alert('Problem!!');
});
// End
}
function getAjaxData(loadUrl, dataObject, action, type) {
return jQuery.ajax({
type: action,
url: loadUrl,
data: dataObject,
dataType: type
});
}
我知道我可以通过在 JS 中执行此操作将其重置为正常:
$('#top_notify').find('.alert').removeClass().addClass('alert'); // The classes it ends up with vary
...但是这样做会在过渡完成之前移除 类 淡出不透明度并且它会立即消失。
我知道我可以在 JS 中做一个延迟来抵消 CSS 的延迟,但是这样做似乎不是一个很好的方法,因为你有两个不同的地方的时间。
有什么方法可以在保持动画由 CSS 完成的同时完成此操作,还是我必须转而使用 jQuery 的 animate
这样我才能 运行 动画完成后的重置程序?
好吧,我想了一个很复杂的方法后想出了一个简单的解决方案哈。
我首先应该想到的简单解决方案是 删除 任何额外添加的 classes before ajax
呼唤;我太专注于在 ajax
块内做这件事,当然这没有用,但在我开始尝试其他解决方案之前,我从未尝试过。
无论如何,简单的解决方案就是简单地移动这段代码:
var alert_el = $('#top_notify').find('.alert');
...在 ajax
调用之上,而不是在其中。
然后直接在下面添加:
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
完整功能代码为:
function myFunc() {
// Set file to prepare our data
var loadUrl = "https://crossorigin.me/http://codepen.io/gutterboy/pen/ObjExz.html";
var alert_el = $('#top_notify').find('.alert');
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
// Run request
getAjaxData(loadUrl, null, 'POST', 'html')
.done(function(response) {
// Update msg in alert box
alert_el.text(response);
alert_el.addClass('alert-success');
// Slide in alert box
alert_el.addClass('visible');
})
.fail(function() {
alert('Problem!!');
});
// End
}
CodePen: http://codepen.io/gutterboy/pen/xRXbXy
我想出的另一个解决方案,虽然现在并不真正需要,但我想我还是会 post 以防将来它对我(或其他人)派上用场。
它 不会 在动画完成后删除 visible
class (因为我不知道什么时候可以提醒 JS它完成了)但是 visible
class - 如果你使用这个方法我会改变它的名字 - 没有添加任何新的样式,它只是 运行是动画。
我是这样做的:
JavaScript和上面的解决方案一样,都是在CSS.
TLDR;
基本上是使用多个CSS动画来控制效果运行时间内的不同状态; CodePen 在底部。
在 .visible
class 中进行了更改并添加了一些 @keyframes
。
.可见class:
&.visible {
animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s;
}
如您所见,我们在这里去掉了任何额外的样式 - 这意味着当动画完成后,它基本上 重置 回到正常状态,这正是我们想要的。
现在,让我们分解这段代码:
我们在这里 运行 设置了 3 种不同的动画,重要的是要注意它们不会 运行 一个接着一个 - 这意味着它们不会等到一个完成后再开始下一个,因此我们需要包含 delay
设置。
所以首先我们从 slideDown
动画开始:
slideDown 0.8s 0s
如果您不熟悉 CSS 中的动画,那么基本上它的作用是在开始 运行ning 和动画 运行s 之前设置 0s
的延迟对于 0.8s
,这是动画:
@keyframes slideDown {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}
所以,非常简单,只需使用 transform
将它从 -100%
向下滑动到 0%
并且这个动画需要 0.8s
正如我们在调用这个动画时设置的那样.
现在,我希望它在开始消失之前保持 可见 3 秒,但我们遇到了问题;一旦动画结束,它就会回到它的标准样式,在我们的例子中,这意味着它在回到 transform: translateY(-100%)
时消失,因为我们在 .visible
class 中没有额外的样式,并且我们不能在其中放置任何额外的样式,因为那样我们将无法重置它回到它的原始状态(样式方面)。
但是我们该怎么办? fadeAway
动画在另外 3 秒内没有开始,目前它没有任何可以淡出的东西(是的,但是你看不到它,因为它是隐藏的)。
解决方案是添加另一个动画 - 从技术上讲,它并没有真正为任何东西添加动画,它只是在 fadeAway
动画开始之前保持可见。
这就是我们到达的地方:
keepThere 3s 0.8s
现在,记住我们的 fadeAway
动画的设置是: fadeAway 1s 3.8s
这意味着我们有 3 秒 动画开始和因此在我们可以用它控制任何样式之前。
这就是这些参数值的用武之地——我们将延迟设置为 0.8s
,因此 keepThere
动画在 slideDown
动画结束后才会开始;然后我们设置 3s
的持续时间来计算 fadeAway
动画开始之前的等待时间,这是 keepThere
动画:
@keyframes keepThere {
0%, 100% {
transform: translateY(0%);
}
}
由于它具有相同的开始和结束样式,我们将其合并到 0%, 100%
的一个选择器中,如您所见,这正如它所说的那样,使元素在设定的持续时间内可见3s
直到我们可以使用 fadeAway
动画控制样式。
我想从技术上讲,如果您想在 % 等于 3 秒 时进行数学运算,您可以将此功能组合到 fadeAway
动画中,从而知道何时开始淡出元素。
最后我们有 fadeAway
动画:
fadeAway 1s 3.8s
现在正如我们上面所讨论的,我们已经知道为什么我们将 delay
设置为 3.8s
,0.8s
偏移量以允许 slideDown
动画 运行 和一个额外的 3s
延迟,因为这是我们希望元素可见的时间,直到它开始消失,然后当然需要 1s
才能完成。
这个动画是:
@keyframes fadeAway {
0%, 100% {
transform: translateY(0%);
}
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
现在,由于 keepThere
动画已经完成,我们必须确保保持元素可见,以便淡入淡出有一些可见的东西实际淡出,这就是为什么我们确保包含样式 transform: translateY(0%);
作为从头到尾的一个值;在那之后,我想它在做什么就很明显了。
把它们放在一起你会得到:
.top-notify {
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
.content {
text-align: center;
background-color: transparent;
transform-style: preserve-3d;
}
.alert {
display: inline-block;
transform: translateY(-100%);
min-width: 250px;
max-width: 500px;
border-top-left-radius: 0;
border-top-right-radius: 0;
&.visible {
animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s;
}
}
}
@keyframes slideDown {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}
@keyframes keepThere {
0%, 100% {
transform: translateY(0%);
}
}
@keyframes fadeAway {
0%, 100% {
transform: translateY(0%);
}
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
CodePen: http://codepen.io/gutterboy/pen/QGqwBg
当然,为了能够再次 运行,必须重新添加 class,因此这就是删除 .visible
class 的目的在每个 运行 的开头(在 ajax 调用之前),然后在 ajax 期间重新添加时调用它 运行s 再次.
感谢@Nathaniel Flick 分享 link 引导我走上这条道路的开始:)
好吧,希望这对 某人 有用,因为我不会再使用该选项了哈!
好的,我有一种情况,我基本上构建了一个小的通知下拉框,当用户做某事时,它会在最后转换到 opacity: 0;
状态。
但是,因为用户可能会单击其他会再次触发此通知框的东西,所以我正在尝试想出一种方法将其重置为正常状态,而不影响任何正在进行的转换并尝试保持动画完成通过 CSS 而不是 JavaScript.
CodePen:http://codepen.io/gutterboy/pen/WoEydg
HTML:
<a href="#">Open Notify Window</a>
<div id="top_notify" class="top-notify">
<div class="container-fluid">
<div class="row">
<div class="content col-xs-12">
<div class="alert" role="alert"></div>
</div>
</div>
</div>
</div>
SCSS:
body {
text-align: center;
padding-top: 150px;
}
.top-notify {
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
.content {
text-align: center;
background-color: transparent;
transform-style: preserve-3d;
}
.alert {
display: inline-block;
transform: translateY(-100%);
min-width: 250px;
max-width: 500px;
border-top-left-radius: 0;
border-top-right-radius: 0;
&.visible {
transform: translateY(0%);
transition: 0.8s 0s, opacity 1s 3.8s;
opacity: 0;
}
}
}
JS:
$('a').on('click', function(e){
e.preventDefault();
myFunc();
});
function myFunc() {
// Set file to prepare our data
var loadUrl = "https://crossorigin.me/http://codepen.io/gutterboy/pen/ObjExz.html";
// Run request
getAjaxData(loadUrl, null, 'POST', 'html')
.done(function(response) {
var alert_el = $('#top_notify').find('.alert');
// Update msg in alert box
alert_el.text(response);
alert_el.addClass('alert-success');
// Slide in alert box
alert_el.addClass('visible');
})
.fail(function() {
alert('Problem!!');
});
// End
}
function getAjaxData(loadUrl, dataObject, action, type) {
return jQuery.ajax({
type: action,
url: loadUrl,
data: dataObject,
dataType: type
});
}
我知道我可以通过在 JS 中执行此操作将其重置为正常:
$('#top_notify').find('.alert').removeClass().addClass('alert'); // The classes it ends up with vary
...但是这样做会在过渡完成之前移除 类 淡出不透明度并且它会立即消失。
我知道我可以在 JS 中做一个延迟来抵消 CSS 的延迟,但是这样做似乎不是一个很好的方法,因为你有两个不同的地方的时间。
有什么方法可以在保持动画由 CSS 完成的同时完成此操作,还是我必须转而使用 jQuery 的 animate
这样我才能 运行 动画完成后的重置程序?
好吧,我想了一个很复杂的方法后想出了一个简单的解决方案哈。
我首先应该想到的简单解决方案是 删除 任何额外添加的 classes before ajax
呼唤;我太专注于在 ajax
块内做这件事,当然这没有用,但在我开始尝试其他解决方案之前,我从未尝试过。
无论如何,简单的解决方案就是简单地移动这段代码:
var alert_el = $('#top_notify').find('.alert');
...在 ajax
调用之上,而不是在其中。
然后直接在下面添加:
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
完整功能代码为:
function myFunc() {
// Set file to prepare our data
var loadUrl = "https://crossorigin.me/http://codepen.io/gutterboy/pen/ObjExz.html";
var alert_el = $('#top_notify').find('.alert');
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
// Run request
getAjaxData(loadUrl, null, 'POST', 'html')
.done(function(response) {
// Update msg in alert box
alert_el.text(response);
alert_el.addClass('alert-success');
// Slide in alert box
alert_el.addClass('visible');
})
.fail(function() {
alert('Problem!!');
});
// End
}
CodePen: http://codepen.io/gutterboy/pen/xRXbXy
我想出的另一个解决方案,虽然现在并不真正需要,但我想我还是会 post 以防将来它对我(或其他人)派上用场。
它 不会 在动画完成后删除 visible
class (因为我不知道什么时候可以提醒 JS它完成了)但是 visible
class - 如果你使用这个方法我会改变它的名字 - 没有添加任何新的样式,它只是 运行是动画。
我是这样做的:
JavaScript和上面的解决方案一样,都是在CSS.
TLDR;
基本上是使用多个CSS动画来控制效果运行时间内的不同状态; CodePen 在底部。
在 .visible
class 中进行了更改并添加了一些 @keyframes
。
.可见class:
&.visible {
animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s;
}
如您所见,我们在这里去掉了任何额外的样式 - 这意味着当动画完成后,它基本上 重置 回到正常状态,这正是我们想要的。
现在,让我们分解这段代码:
我们在这里 运行 设置了 3 种不同的动画,重要的是要注意它们不会 运行 一个接着一个 - 这意味着它们不会等到一个完成后再开始下一个,因此我们需要包含 delay
设置。
所以首先我们从 slideDown
动画开始:
slideDown 0.8s 0s
如果您不熟悉 CSS 中的动画,那么基本上它的作用是在开始 运行ning 和动画 运行s 之前设置 0s
的延迟对于 0.8s
,这是动画:
@keyframes slideDown {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}
所以,非常简单,只需使用 transform
将它从 -100%
向下滑动到 0%
并且这个动画需要 0.8s
正如我们在调用这个动画时设置的那样.
现在,我希望它在开始消失之前保持 可见 3 秒,但我们遇到了问题;一旦动画结束,它就会回到它的标准样式,在我们的例子中,这意味着它在回到 transform: translateY(-100%)
时消失,因为我们在 .visible
class 中没有额外的样式,并且我们不能在其中放置任何额外的样式,因为那样我们将无法重置它回到它的原始状态(样式方面)。
但是我们该怎么办? fadeAway
动画在另外 3 秒内没有开始,目前它没有任何可以淡出的东西(是的,但是你看不到它,因为它是隐藏的)。
解决方案是添加另一个动画 - 从技术上讲,它并没有真正为任何东西添加动画,它只是在 fadeAway
动画开始之前保持可见。
这就是我们到达的地方:
keepThere 3s 0.8s
现在,记住我们的 fadeAway
动画的设置是: fadeAway 1s 3.8s
这意味着我们有 3 秒 动画开始和因此在我们可以用它控制任何样式之前。
这就是这些参数值的用武之地——我们将延迟设置为 0.8s
,因此 keepThere
动画在 slideDown
动画结束后才会开始;然后我们设置 3s
的持续时间来计算 fadeAway
动画开始之前的等待时间,这是 keepThere
动画:
@keyframes keepThere {
0%, 100% {
transform: translateY(0%);
}
}
由于它具有相同的开始和结束样式,我们将其合并到 0%, 100%
的一个选择器中,如您所见,这正如它所说的那样,使元素在设定的持续时间内可见3s
直到我们可以使用 fadeAway
动画控制样式。
我想从技术上讲,如果您想在 % 等于 3 秒 时进行数学运算,您可以将此功能组合到 fadeAway
动画中,从而知道何时开始淡出元素。
最后我们有 fadeAway
动画:
fadeAway 1s 3.8s
现在正如我们上面所讨论的,我们已经知道为什么我们将 delay
设置为 3.8s
,0.8s
偏移量以允许 slideDown
动画 运行 和一个额外的 3s
延迟,因为这是我们希望元素可见的时间,直到它开始消失,然后当然需要 1s
才能完成。
这个动画是:
@keyframes fadeAway {
0%, 100% {
transform: translateY(0%);
}
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
现在,由于 keepThere
动画已经完成,我们必须确保保持元素可见,以便淡入淡出有一些可见的东西实际淡出,这就是为什么我们确保包含样式 transform: translateY(0%);
作为从头到尾的一个值;在那之后,我想它在做什么就很明显了。
把它们放在一起你会得到:
.top-notify {
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
.content {
text-align: center;
background-color: transparent;
transform-style: preserve-3d;
}
.alert {
display: inline-block;
transform: translateY(-100%);
min-width: 250px;
max-width: 500px;
border-top-left-radius: 0;
border-top-right-radius: 0;
&.visible {
animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s;
}
}
}
@keyframes slideDown {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}
@keyframes keepThere {
0%, 100% {
transform: translateY(0%);
}
}
@keyframes fadeAway {
0%, 100% {
transform: translateY(0%);
}
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
CodePen: http://codepen.io/gutterboy/pen/QGqwBg
当然,为了能够再次 运行,必须重新添加 class,因此这就是删除 .visible
class 的目的在每个 运行 的开头(在 ajax 调用之前),然后在 ajax 期间重新添加时调用它 运行s 再次.
感谢@Nathaniel Flick 分享 link 引导我走上这条道路的开始:)
好吧,希望这对 某人 有用,因为我不会再使用该选项了哈!