从元素中删除 类 而不影响正在进行的 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.8s0.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 引导我走上这条道路的开始:)

好吧,希望这对 某人 有用,因为我不会再使用该选项了哈!