Triggering a CSS animation again with a JavaScript event - javascript

I'm trying to trigger a CSS animation again with JavaScript. Tried a lot of tricks, nothing works.
Steps:
<canvas class="shake"> is added to document.body
shake animation works!
Press "Shake" button to re-add the CSS.
Animation does not get triggered again.
Code
https://jsbin.com/pasitic/edit?css,js,console,output
The code is really simple. I'm hoping that there is a really simple and decent solution out there. I'm using vanilla JavaScript.
Update
Solved and the example was updated with the working code.

Try this:
...
$btn.addEventListener("click", function(e) {
e.preventDefault();
console.log("clicked");
$canvas.className = "shake"; // Doesn't trigger the animation!
});
$canvas.addEventListener("animationend", function(e) {
$canvas.className = "";
});
...
It adds an event listener that removes the class name which triggers after the animation ends.

If you remove a class and add it again the animation won't play.
You could wrap the add "shake" class in a setTimeout function with a tiny delay and the animation will work.
$canvas.className = "";
setTimeout(function(){
$canvas.className = "shake";
}, 50);
Also you could use the following:
$canvas.classList.remove("shake");
void $canvas.offsetWidth;
$canvas.classList.add("shake");
The $canvas.offsetWidth; will trigger a reflow.
You can read more about it here:
https://css-tricks.com/restart-css-animation/

Adding the timeout with some delay worked. I have added the delay equal to animation-duration but adding any amount of delay will work.
$btn.addEventListener("click", function(e) {
e.preventDefault();
console.log("clicked");
$canvas.className = 'shake';
setTimeout(function(){ $canvas.className = ''; }, 500);
});

Related

setTimeout trigger on scroll

I'm trying to delay a timeout effect, currently the effect starts when the page is loaded, I want it to start when I scroll to a certain div
Here is how it currently is
I did some searching and found a library called waypoint that allows to trigger events based on waypoints using the code below but no luck.I also tried setting the display to none and change it once the css animation was triggered but when it appeared on the page the progress bars were already in place.
var waypoint = new Waypoint({
element: document.getElementById('waypoint'),
handler: function(direction) {
console.log('Scrolled to waypoint!')
}
})
So, here is the JSFiddle that I could come up with.
https://jsfiddle.net/md0m60cb/6/
Have a look at the CSS, i changed some ID's into classes there. With that, I did the following in the Javascript:
$(document).ready(function () {
$('#startAnimation').waypoint(function () {
setTimeout(function () {
$('#progress-html').addClass('progress-html-class');
}, 2800);
setTimeout(function () {
$('#progress-css').addClass('progress-css-class');
}, 3500);
setTimeout(function () {
$('#progress-javascript').addClass('progress-javascript-class');
}, 4200);
setTimeout(function () {
$('#progress-php').addClass('progress-php-class');
}, 4900);
setTimeout(function () {
$('#progress-angular').addClass('progress-angular-class');
}, 5600);
});
});
So, what does it do? Using JQuery, I assigned a waypoint to the row that holds the animations (with the id #startAnimation). As soon as it reaches that waypoint, I set timeouts with the varying delays that add the necessary css classes, which in turn trigger the animation.
I hope I could clarify what I did here. If you have questions, just reply.
using javasript function onscroll(). set the the onscroll function to the div tag and set animation using setTimeOut() and clearTimeOut().
the event function onscroll() will trigger the animation until it reaches the target div tag it stops.

Add a delay to jQuery fadeIn function

I am trying to add a delay to my fadeIn function in jQuery. The purpose of the code is that when 'topmods' or 'dailyskins' button is pressed it will hide/show the other parent div.
Currently when i press the div 'topmods' is does hide the div 'dailyskins' though the content of 'topmods' goes below 'dailyskins' for a split second until 'dailyskins' has finished fading out.
I think this would be solved by adding a delay to both fadeIn and Out, though i don't know how to add this,
Please could you add a delay of 200ms to each of the fadeIn segments.
jQuery(document).ready(function(){
$("#topmods").hide();
jQuery('#dropdailyskin').live('click', function(event) {
jQuery('#dailyskins').fadeIn('show');
});
jQuery('#dropdailyskin').live('click', function(event) {
jQuery('#topmods').fadeOut('show');
});
jQuery('#dropdownmods').live('click', function(event) {
jQuery('#dailyskins').fadeOut('show');
});
jQuery('#dropdownmods').live('click', function(event) {
jQuery('#topmods').fadeIn('show');
});
Thanks
Just add the .delay to your code like this
$("idhere").delay(1000).fadeIn(500);
its in milliseconds.
You can add a timeout before executing your function using this:
setTimeout(function(){jQuery('#dailyskins').fadeIn('show')}, 200);
or you can use.
$("idhere").delay(1000).show();

Bootstrap Hover slideUp slideDown Animation

I use this code to make bootstrap dropdown show when mouse hover
var bMobile; // true if in mobile mode
// Initiate event handlers
function init() {
"use strict";
// .navbar-toggle is only visible in mobile mode
bMobile = $('.navbar-toggle').is(':visible');
var oMenus = $('.navbar-nav .dropdown'),
nTimer;
if (bMobile) {
// Disable hover events for mobile
oMenus.off();
} else {
oMenus.on({
'mouseenter touchstart': function(){
event.preventDefault();
clearTimeout(nTimer);
oMenus.removeClass('open');
$(this).addClass('open');
},
'mouseleave': function() {
nTimer = setTimeout(function() {
oMenus.removeClass('open');
}, 500);
}
});
}
}
$(document).ready(function() {
// Your other code to run on DOM ready...
init();
});
$(window).resize(init);
I use this code to remove hover effect from small screens and work on big screens
How can make this code slide animation ?
and if there is code better than this code please add it in comment
I am bad in English, sorry :)
I recommend using the http://daneden.github.io/animate.css/ project, and adding the css class you want, i'll try to throw together a quick example
Here's a quick and dirty demo
$($(this).find(".dropdown-menu")[0]).addClass('bounceInUp animated');
http://jsfiddle.net/L8nz8zk2/1/
you would want to use something like this to handle the mouse events (no need for the $.on()):
http://api.jquery.com/hover/
so your code would look something like this.
$('CSS SELECTOR OF THE ITEM TO HOVER OVER').hover(function(){
$('CSS SELECTOR OF THE ITEM THAT NEEDS TO SLIDE DOWN').slideDown();
},function(){
$('CSS SELECTOR OF THE ITEM THAT NEEDS TO SLIDE UP').slideUp();
});
The Jquery animation of slideDown() and slideUp() is what you're looking for, and this combined with the .hover() jquery event handler should be able to give you what you need.
you can lose the .on() calls.

jQuery: Delay a mouseenter event (dropdown menu)

I'm working on this fiddle: http://jsfiddle.net/8n2TQ/9/
It consists of a rollover button which drops down a menu like so:
$('#one').mouseenter(function() {
//Slide down
});
The event happens immediately on hover, but I want to put in a small delay to prevent accidental hovers from triggering the event. I tried to work with a timer (see http://jsfiddle.net/8n2TQ/13/) but that doesn't seem to execute all the events under '//Slide up'. I guess I'm missing something here, what am I doing wrong?
https://github.com/briancherne/jquery-hoverIntent
There is a plugin for this that works well.
You asked how to handle function. There is an example on thé plugin page
var config = {
over: makeTall, // function = onMouseOver callback (REQUIRED)
timeout: 500, // number = milliseconds delay before onMouseOut
out: makeShort // function = onMouseOut callback (REQUIRED)
};
$("#demo3 li").hoverIntent( config )

jQuery: Prevent stacking animations

I know there are several other posts with solutions to this, but my current problem is a little different.
I have two events on an element - mouseenter and mouseleave. The first changed the color of my element to light and the other back to dark, this makes a flashing effect.
The problem is when I go in and out a couple of times the events stack and it flashes many times even if no new events are triggered. I would like to prevent that, but .stop() does not help.
Here's the catch: I would like to trigger 1 flash no matter what, but not more than 1. So when someone moves in / out - the event mouseenter will be fired, after it mouseleave and after it nothing.. until another in / out is triggered.
I guess this could be made by locking (not listening for) new events when in / out is triggered up until the effect has finished, but I don't know how to do without unbinding and binding it again. Isn't there any lockEvent() or something?
Have you already used .stop(true) or .stop(true, true)?
there is pseudo-class in jQuery ":animated"
you can use it on first mouseenter even like:
if ( $(this).is(':animated')) {
return false;
}
to prevent additional animation
You can try just setting a bool var and firing only if false...
var anim = {
animating: false,
over: function(){
if(!anim.animating)
{
anim.animating = true;
// do you animation here
// and set your animating bool to false before calling outro...
$('#elem').animate({/*some css change*/ }, 1000, function(){
anim.animating = false;
anim.out();
});
}
},
out: function(){
if(!anim.animating)
{
anim.animating = true;
//do your outro animation here
$('#elem').animate({/*some css change*/ }, 1000, function(){
anim.animating = false;
});
}
}
};
then have your listener call anim.over and anim.out...
$('#elem').on('mouseenter', function(){
anim.over();
}).on('mouseleave', function(){
anim.out();
});
This way you will call animation on enter and it will automatically fire off the outro animation when the intro completes.

Categories

Resources