1


I'm making a website which will let you update an SQL table, and I want to add some sort of feedback when a button is clicked. I have made an invisible button (opacity=0) which lies to the right of each row as a status. I made this JS fade() function to set the opacity to 1, then slowly bring it back to 0, so a message pops up then fades away.

 function fade () {
    var invis = document.getElementById("invis".concat(num.toString()));
        if(invis.style.opacity > .990) {
            invis.style.opacity = (invis.style.opacity) - .001;
            setTimeout(fade, 50);
        } else if(invis.style.opacity > 0) {
            invis.style.opacity = (invis.style.opacity) - .05;
            setTimeout(fade, 50);
        }
    }

The trouble is, since webpages are single-threaded, any other action will interrupt the animation and leave behind a half-faded status. So that's no good. So now I am trying to set up the invisible buttons to change class when a new row is updated. The new class looks like this:

.invisible_anim {
    ...
    opacity: 0;
    animation:trans 3000ms;
}
@keyframes trans {
    0% {
       opacity: 1;
    } 
    50% {
        opacity: 1;
    }

This works fine, except it only works once. From here I cannot get the animation to play a second time. I have tried changing the class back to "invisible" then "invisible_anim" with no luck. I also can't use JQuery or Webkit. I'm wondering if there's some flag you can set for a button without actually clicking on it so I can reset the class when I need to? Or even some way to thread my JS function so I can stick with that.

Lord Farquaad
  • 712
  • 1
  • 12
  • 33

3 Answers3

1

If you would like to play the animation multiple times (see docs here: https://developer.mozilla.org/en-US/docs/Web/CSS/animation), if you would like to play it twice only.

so this:

.invisible_anim {
...
opacity: 0;
animation:trans 3000ms;
}
@keyframes trans {
0% {
   opacity: 1;
} 
50% {
    opacity: 1;
}

would turn to

.invisible_anim {
...
opacity: 0;
animation:trans 3s 2 ;
}

@keyframes trans {
0% {
   opacity: 1;
} 
50% {
    opacity: 1;
}

EDIT: Apparently the requirements are different than what I thought. Instead the solution seems to be to key off the animation event located at https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations and then when that animation done do what you need to do: so in JS-only

var e = document.getElementById("watchme");
e.addEventListener("animationend", listener, false);

function listener(){
   //do what you need to do here
}

Just be careful, the reason for this is that most browsers have different "animationend" events that fire at different times. So definitely will need to be tested in different browsers to make sure that the animation event is firing at the right time. There's a post at (https://css-tricks.com/controlling-css-animations-transitions-javascript/) that details some of the issues you might encounter.

Daemedeor
  • 1,013
  • 10
  • 22
  • Thanks, but the trouble is I need to get it to play once per event. A click on the button in front of it is what triggers it to animate. I know there's something in CSS like .button + invisible_anim, which only affects the invisible_anim if it's immediately following a button. Would it be possible to set the animation to constantly fade to 0 (with "infinite") then set up an onclick for the button to set the opacity of our invisible_anim to 1? I'm not sure if the animation would let that happen... – Lord Farquaad Aug 13 '15 at 19:08
  • @LordFarquaad you should then just append a class to the element in question with the onclick event, and that would then make everything fade. infinite actually just plays the animation back over again. so it would go from 0 to 1 then restart all over again. You can apply another class like .invisible.invisibleanim later in your css to have different properties and override the rest – Daemedeor Aug 13 '15 at 19:12
  • Actually, I used the listener you put in the comment to Blake's answer and it worked perfectly, thanks! I'm gunna edit my question to put that solution in, but if you submit it as an answer I'll gladly check it off. – Lord Farquaad Aug 13 '15 at 19:15
  • @LordFarquaad thanks! i was a bit unsure of what you were asking though my original answer alllows you to play the event twice, so i'm leaving it up there in case someone comes looking at your post with that intent and just replaying the information, i gave a little bit more information at the end of the post based on the comment i left – Daemedeor Aug 13 '15 at 19:35
1

Have you considered using the CSS property "transition"? JavaScript has an event listener called "transitionend" that can trigger when your transition has ended, which you can use to reset the button.

First set the area for your alert button with the id invis.

CSS:

#invis {    
    opacity: 1;
    transition: opacity 3s;
}

Then in JavaScript, generate your button and its content, which will appear at opacity 1, then transition to opacity 0. Your addEventListener will trigger when the animation is done, remove the button and reset the opacity for the next trigger.

JavaScript:

var invis = getElementByID("invis");

function fade() {
    var button = document.createElement("button");
    invis.appendChild(button);
    invis.style.opacity = ("0");

    invis.addEventListener("transitionend", function(){
        invis.removeChild(button);
        invis.style.opacity = ("1");
    });
}

You can add the fade() function to your EventListener for the user "click."

This is my first time answering on StackOverflow, I hope this helps!

George F
  • 46
  • 4
0

You need to start transparent then show then hide:

@keyframes trans {
    0% {
       opacity: 0;
    } 
    50% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}

Then simply add your class (remove after the 3000ms time period)

Blake A. Nichols
  • 870
  • 1
  • 6
  • 11
  • I've tried something like that, but the trouble is I don't know when the 3 seconds are up without some sort of listener, and then I run into the same trouble I had with the JS function. – Lord Farquaad Aug 13 '15 at 18:47
  • You could do: $(element).addClass( 'invisible_anim' ); setTimeout( $(element).removeClass( 'invisible_anim' ), 3000 ); if you are using jquery – Blake A. Nichols Aug 13 '15 at 18:50
  • While that would be great, I stuck without jQuery – Lord Farquaad Aug 13 '15 at 19:00
  • @BlakeA.Nichols there's an event that fires at the end of the animation, you wouldn't even need to use jQuery, though it makes listening to all the animtation events easier (each browser fires the event at different times). but instead, he can have the animtation play 2ce... that's another option – Daemedeor Aug 13 '15 at 19:01
  • I'm intrigued yet confused. How do I tell the code to respond to this event? – Lord Farquaad Aug 13 '15 at 19:03
  • @LordFarquaad well you basically do document.addEventListener(event, callback)/ you'll need to look up all the different events cause i don't have them memorized (see docs here: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations) , however, i shared a solution without having to deal with all those window events and just leverage what animation already provides – Daemedeor Aug 13 '15 at 19:06
  • Very nice, I didn't realize they had added callbacks for animations yet. Here is a bit of info for it: http://stackoverflow.com/questions/2794148/css3-transition-events – Blake A. Nichols Aug 13 '15 at 20:07