2

I am trying to make a kind of template, for a dashboard page, where when a dashboard button is clicked, something is added to the DOM.

I was trying to template this, so that when someone makes a new dashboard for example, he has the option, to specify in CSS an animation that should run on each button when clicked. If an animation is defined on the button, the actual loading of the element should be delayed until the animation completes.

Now, if I actually specify an animation in css, everything works fine, because I am delaying the logical code with a callback on the animations end. My problem is, that I can't achieve the same, when there is no animation set to the element.

What I would want is something simmilar:

function buttonClick($button) {
     $button.addClass('activated');
     $button.one('animationend', function() {
         // ... run the logic here
     });

     if (...no animation specified in activated class) {
        // ... run the logic here
     }
}

NOTE: I am using jQuery here, if there is a method specific in jQuery for this, that would also be okay for me, but a plain javascript method would be fine as well. I heard about the jQuery(":animated") selector, but when I was testing it, it seems that it only works for animations started with jQuery itself, and not with CSS3.

Adam Baranyai
  • 3,635
  • 3
  • 29
  • 68
  • 1
    [https://stackoverflow.com/questions/14796936/how-do-you-detect-when-css-animations-start-and-end-with-javascript](https://stackoverflow.com/questions/14796936/how-do-you-detect-when-css-animations-start-and-end-with-javascript) – Sfili_81 Jun 18 '20 at 09:25
  • 1
    Maybe just add a “pseudo animation” then to those buttons, that did not get an explicit one assigned by the user? It would not actually have to _do_ anything, and the animation duration could be minimal - but it will trigger `animationend`, so you would not have to go an code two different branches (and solve your “detection problem” in the first place.) – CBroe Jun 18 '20 at 09:37
  • @CBroe that indeed could be a solution, but I was looking for a more cleaner, non-hacky like one:) but if nothing else comes up, that's a good backup also. – Adam Baranyai Jun 18 '20 at 09:40
  • @Sfili_81 what if an animation was already running, and then I change it to another animation, will `animationstart` still fire? – Adam Baranyai Jun 18 '20 at 09:41

1 Answers1

3

As you seem to use animation CSS for your animations (given that you use the animationend event), you could use getComputedStyle to verify the content of the animation-name CSS property.

Here is a demo with two buttons: one triggers an animation on click, while the other doesn't:

$("button").click(function () {
    buttonClick($(this));
});

function hasAnimation($button) {
    return getComputedStyle($button[0], null)["animation-name"] != "none";
}

function onEndAnimation($button) {
    $button.removeClass('activated');
    console.log("animation complete on button " + $button.text());
}

function buttonClick($button) {
    $button.addClass('activated');
    $button.one('animationend', () => onEndAnimation($button));
    if (!hasAnimation($button)) onEndAnimation($button);
}
#yes.activated {
    animation-duration: 1s;
    animation-name: grow;
}

@keyframes grow {
  from { width: 50px; }
  50% { width: 100px; }
  to { width: 50px; }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="yes" style="width: 50px">Yes</button><br>
<button id = "no" style="width: 50px">No</button>
trincot
  • 317,000
  • 35
  • 244
  • 286