Removing classes from an element without affecting css transitions

Well, I have a situation where I basically built a small drop-down notification window that occurs when the user does something, at the end he goes into opacity: 0; state opacity: 0; .

However, since the user can click something else that starts this notification window again, I am trying to find a way to return to normal reset without affecting any progressive transitions and trying to save the CSS animation, not 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 }); } 

I know that I can reset back to normal by doing this in JS:

 $('#top_notify').find('.alert').removeClass().addClass('alert'); // The classes it ends up with vary 

... however, this removes the classes before the transition is completed, decreasing the opacity and disappearing immediately.

I know that I can do a delay in JS to counteract CSS delay, but doing it this way just doesn't seem like a very good way to do this, since you have timings in two different places.

Is there a way to do this while preserving the animation done with CSS, or do I need to switch to using jQuery animate so that I can start the reset procedure after the animation finishes?

+7
javascript jquery css css-transitions transition
source share
1 answer

Well, I came up with a simple solution after I came up with a curved one ha.

The simple solution I had to come up with was to remove any additional added classes before calling ajax ; I'm too focused on doing this in the ajax block, and of course it didn’t work, but until I started playing with another solution, I never tried it.

In any case, a simple solution simply moves this code:

  var alert_el = $('#top_notify').find('.alert'); 

... above the ajax call, and not be inside it.

Then adding this directly below it:

 alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning'); 

With full function code:

 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

Another solution that I came across, although I didn’t really need it now, I thought that I would publish it anyway if it came in handy (or to someone) in the future.

It does not delete the visible class after the animation is complete (since I don’t know how to warn JS, but the visible class), which I would change the name if you use this method - do not add any new styles, it just starts the animation.

Here is how I did it:

JavaScript remains the same as the solution above, all in CSS.

TL; DR;

It mainly uses several CSS animations to control different states during the execution of an effect; CodePen below.

Changes to the .visible class and the addition of some @keyframes .

.visible class:

 &.visible { animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s; } 

As you can see, we got rid of any additional style here - this means that when the animation is completed, it is essentially reset to its normal state, which is what we want.

Now leave this code:

Here we run 3 different animations, and it is important to note that they do not start one after another, which means that they do not wait for one of them to finish until it starts the next one, so we had to enable delay .

So, first we start with the slideDown animation:

slideDown 0.8s 0s

If you are new to CSS animation, basically what it does is set a delay of 0s before it starts, and the animation starts for 0.8s , and this animation:

 @keyframes slideDown { 0% { transform: translateY(-100%); } 100% { transform: translateY(0%); } } 

So, quite simply, it simply reduces it with transform from -100% to 0% , and this animation takes 0.8s , as we set in our call to this animation.

Now I wanted it to remain visible for 3 seconds before it starts to fade, but we have a problem; as soon as the animation ends, it returns to the standard styles, which in our case means that it disappears when it returns to transform: translateY(-100%) , since we do not have additional styles in the .visible class, and we cannot add unnecessary styles there, as then, we will not be able to reset it back to its original state (wise style).

But what do we do? The fadeAway animation fadeAway not start for another 3 seconds, and at the moment it has nothing to disappear (well, but it’s not, but you cannot see it as hidden).

The solution to this was to add another animation that technically doesn’t revive anything, it just saves it until the fadeAway animation fadeAway .

What do we get:

keepThere 3s 0.8s

Now, remembering the settings of our fadeAway animation: fadeAway 1s 3.8s , this means that we have 3 seconds before this animation starts and, therefore, before we can control any style with it.

So, when these parameter values ​​come in - we set the delay to 0.8s , so the keepThere animation keepThere not start until slideDown completes; then we set the duration for 3s for the timeout counter before the fadeAway animation fadeAway , and this is the keepThere animation:

 @keyframes keepThere { 0%, 100% { transform: translateY(0%); } } 

Since it has the same start and end style, we combine it into one selector 0%, 100% , and, as you can see, it does what it says it does, keeps the element visible for a given 3s duration until while we can control the fadeAway animation fadeAway .

I assume that technically you could combine this functionality into a fadeAway animation if you want to do the math with% being 3 seconds , and therefore know when to start fading the element.

Finally, we have the fadeAway animation:

fadeAway 1s 3.8s

Now, as we said above, we already know why we set the delay offset to 3.8s , 0.8s so that the slideDown animation starts, and an additional 3s delay, as we want the element to be visible until it is visible will begin to fade, and then, of course, the attenuation will take 1s .

Animation for this:

 @keyframes fadeAway { 0%, 100% { transform: translateY(0%); } 0% { opacity: 1; } 100% { opacity: 0; } } 

Now that the keepThere animation keepThere complete, we need to make sure that the element is visible, so Fade has something visible that really disappears, so we will definitely enable the transform: translateY(0%); style transform: translateY(0%); as a value from start to finish; after that it is quite obvious what I think.

Put it all together and you will get:

 .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

Then, of course, in order to run it again, the class must be re-added, and therefore the goal was to remove the .visible class at the beginning of each run (before calling ajax), and then when it is added again during the ajax call again.

Thanks to @Nathaniel Flick for sharing the link that led me along this path to start with :)

Well, I hope that this will be useful for those who see, since I will no longer use this option ha!

+1
source share

All Articles