jQuery animations break after some time - javascript

When I stay in my div the animation won't work again if I go out and in again... So like when I stay in the field while the animation is playing when I quit and go back in it again, it doesn't start the animation over again..
HTML:
<div class="ani-bounce-slow" style="height: 200px; width: 50%; background-color: #3c3; ">
<p> This is a bouncing Text!</p>
</div>
CSS:
.bounce-slow {
animation: bounce 3s;
}
#keyframes bounce {
0%,
20%,
50%,
80%,
100% {
transform: translateY(0);
}
40% {
transform: translateY(-30px);
}
60% {
transform: translateY(-15px);
}
}
jQuery:
$(document).ready(function () {
$('.ani-bounce-slow').mouseenter(function () {
$(this).addClass('bounce-slow');
});
$('.ani-bounce-slow').one('webkitAnimationEnd oanimationend msAnimationEnd animationend',
function (e) {
$(this).removeClass('bounce-slow');
}
);
});
Fiddle here

I think your problem is that you are using one() function instead of on():
Change:
$('.ani-bounce-slow').one('webkitAnimationEnd...
To:
$('.ani-bounce-slow').on('webkitAnimationEnd...
.one( events [, data ], handler )
Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
.on( events [, selector ] [, data ], handler )
Attach an event handler function for one or more events to the selected elements.

Looks like you just need to rip out the class to stop the animation on leave, and just add it back on enter. This will make the animation happen every time.
$('.ani-bounce-slow').mouseenter(function () {
$(this).addClass('bounce-slow');
});
$('.ani-bounce-slow').mouseleave(function () {
$(this).removeClass('bounce-slow');
});
If you want the animation to continue on mouse leave, then you need to check for animation completion, or set a timer for how loong the animation should be.

Related

How to manually trigger the mouseleave event on a mobile device

I want to change a link color to orange on hover.
On a mobile device, when the user touches the link, it becomes orange and will remain orange until the user clicks away. So I want to manually trigger the mouseout event so that the link looses it's hover effect after 1 seconds.
This is what I have tried but the link remains orange after 1 second:
$(window).on('load', function() {
$('a').on('click', function() {
// on a mobile device, I want the hover effect to end after 1 seconds
window.setTimeout(function() {
$('a').trigger('mouseout');
}, 1000);
});
});
a {
font-size: 2rem;
}
a:hover {
color: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<a href='#'>Test</a>
</div>
Note: this is a simplified example, in my code I am not using a timer instead I want to trigger the mouseout event on ajaxcomplete
$(document).on('ajaxComplete', function () {
$('a').trigger('mouseout');
});
The problem is trying to force a mouseout event doesn't seem to work on a touch device.
The series of events that is fired on a touch device starts with a touchstart event - see e.g. MDN
If the browser fires both touch and mouse events because of a single user input, the browser must fire a touchstart before any mouse events.
This snippet remembers that the user has started a touch event and instead of acting on mouse events it sets a class which changes the text color. The same is done on mouse events, which are only acted on when the user is not appearing to be using a touch device on this element.
While it would seem logical to look subsequently for the touchend event on the element, it seems that if the user does a long touch on it, given it is an anchor element, the touchend event is not fired on the element when they remove their finger/pointing device. It is however still fired on the window and so we catch that event and remove the hover class.
let usingTouch = false;
const a = document.querySelector('a');
a.addEventListener('touchstart', function() {
usingTouch = true;
a.classList.add('hover');
});
window.addEventListener('touchend', function() {
usingTouch = true;
setTimeout(function() {
a.classList.remove('hover');
}, 1000);
});
a.addEventListener('mouseover', function() {
if (!usingTouch) a.classList.add('hover');
});
a.addEventListener('mouseout', function() {
if (!usingTouch) a.classList.remove('hover');
});
a {
font-size: 2rem;
}
.hover {
color: orange;
}
<div>
<a href='#'>Test</a>
</div>
a {
font-size: 2rem;
}
a:hover {
color: myanimation 1s 1;
-webkit-animation:myanimation 1s 1;
}
#keyframes myanimation
{
0% {color:orange;}
100% {color:orange;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<a href='#'>Test</a>
</div>
This is solvable via a CSS animation, see the snippet above.

How to avoid setting the on click bind event every time the function is ran

So I made this overlay function, and I've also made it close on click on the overlay its self. Problem is I bind the click event every time I run the function ($overlay.click(function() {...}), and I think this is bad for performance. Any ideas?
function fluidOverlayShow(action, currentElement) {
var $overlay = $('#fluid-overlay');
if (action == 'open') {
$overlay.click(function() {
emgFluidOverlayShow('close', currentElement);
});
$(currentElement).addClass('fluid-bring-front');
$overlay.addClass('fluid-anim-overlay');
$overlay.data('statuson', true);
} else if (action == 'close') {
$overlay.removeClass('fluid-anim-overlay');
$overlay.data('statuson', false);
$('.fluid-header').find('.fluid-bring-front').removeClass('fluid-bring-front');
}
}
$('#overlay_test').mouseover(function() {
fluidOverlayShow('open', '#overlay_test');
});
$('#overlay_test').mouseout(function() {
fluidOverlayShow('close');
});
#fluid-overlay {
display: none;
opacity: 0.3;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #000;
z-index: 1000;
}
#overlay_test {
position: relative;
}
#fluid-overlay.fluid-anim-overlay {
display: block;
-webkit-animation: fade-in-overlay 0.2s 1;
-moz-animation: fade-in-overlay 0.2s 1;
animation: fade-in-overlay 0.2s 1;
}
.fluid-bring-front {
z-index: 1100;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Overlay test
<div id="fluid-overlay"></div>
If you absolutely have to keep the click event in the function then use .on() and .off() and then define .off("click") before you define on("click") like this:
$overlay.off("click").on("click", function() {
emgFluidOverlayShow('close', currentElement);
});
This will remove the event binding before it adds it.
You can even namespace the click event like this so it only removes that instance of click (in case other events get added elsewhere):
$overlay.off("click.fluidOverlayClose").on("click.fluidOverlayClose", function() {
emgFluidOverlayShow('close', currentElement);
});
Or...
...do as Guruprasad Rao suggests and move it out of the function (which is a much better way of handling it).
An alternative implementation uses jQuery's .on() method combined with event delgation. What his means is you allow the click event to bubble up through the DOM to a parent element that will always be there that will capture and process the event rather than having to rebind it to the dynamic element everytime it's created.
This would look something like
$("body").on("click","#fluid-overlay",function() {
//code goes here
});

How can I fire a function after an HTML animation ended?

This is my CSS:
.animated {
transition: 1s;
left: -400px;
}
I want to element after it class name has been set to .animated. and after it finish the transition I want to fire a function. Can someone please suggest me the idea?
You can use transitionEnd event, it's fired when a CSS transition has completed:
function showMessage() {
alert('Transition has finished');
}
var element = document.getElementById("animated");
element.addEventListener("transitionend", showMessage, false);
DEMO

How can I make my function to run the moment the page is running?

I would like to make a function run the moment a person loads my page. No interactivity. The function is loading when someone clicks. I also would like to make the function loop after 1 minute and a half. I tried replacing "click" for window.onload and body.onload but as you may have noticed by now I am a true begginer with javascript. Can someone give me a hand please. For now all I have is this:
// Animate an element by adding a class to it:
// Paramaters:
// anim: the class name to add
// time: animation duration (optional, fallsback to the class)
// cb: an optional callback function to happen once the animation ends
$.fn.animatecss = function(anim, time, cb) {
if (time) this.css('-webkit-transition', time / 1000 + 's');
this.addClass(anim);
if ($.isFunction(cb)) {
setTimeout(function() {
// Ensure that the element is available inside the callback.
$(this).each(cb);
}, (time) ? time : 5000);
}
return this;
};
$(document).ready(function() {
$('.box')click(function() {
$(this).animatecss('blur-out', 5000, function() {
console.log('callback');
});
});
});
.blur-out {
-webkit-filter: blur(8px);
-webkit-transform: scale(1.4, 1.4);
-webkit-transition: all 5s ease-out;
transition: all 5s ease-out;
visibility: hidden;
}
.box {
background:#fff;
margin: 80px;
padding: 20px;
}
<div class="box">
<img src="http://companionplants.com/images/small-plant2.jpg">
</div>
$(document).ready(function() {
$('.box').click(function() {
$(this).animatecss('blur-out', 5000, function() {
console.log('callback');
});
});
// add this line
$('.box').trigger('click');
});
Reference: http://api.jquery.com/trigger/
If I understood correctly, You want to start animation automatically after page is loaded.
Remove event handler for click. Leave code for animation like this:
$(document).ready(function() {
$('.box').animatecss('blur-out', 5000, function() {
console.log('callback');
});
});
For automatically repeating this code, you need to place this code in recursive function with settimeout().
$(document).ready(function() {
function animate(){
$('.box').animatecss('blur-out', 5000, function() {
console.log('callback');
});
setTimeout( animate(), 60000);
}
animate();
});
I hope that there are no errors, I cann't check it now, but I think it will help you

CSS hover event is cancelled if I set opacity by javascript

I try to make a image fadeIn effect, I set jQuery animate method to implement fade-in effect, and I found the hover event which I register in CSS have been cancelled.
I think it's weird, the method should not affect my hover effect.
Although I can re-register hover event by javascript, but it is doing an other task
Is anything I misunderstanding?
P.S. I'm trying to not to use CSS3 animation.
JS part:
$('img').animate({
'opacity': '0.5'
}, 1500);
CSS part:
img {
opacity: 0;
}
img:hover {
opacity: 1;
}
http://jsfiddle.net/aSRMR/
Use !important in css that will solve the problem
img:hover {
opacity: 1 !important;
}
Working Fiddle
You could use hover instead.
$('img').hover( function (){
console.log('hovered in');
}, function (){
console.log('hovered out');
}
Don't forget to put stop() before you do an animate.
so trying your code will look like this.
$('img').hover( function (){
console.log('hovered in');
$('img').stop().animate({'opacity': '1'}, 1500);
}, function (){
console.log('hovered out');
$('img').stop().animate({'opacity': '0.5'}, 1500);
}
Another solution, if you want to do a CSS approach, do it like this.
$('img').hover( function (){
$('img').addClass('hovered');
}, function (){
$('img').removeClass('hovered');
}
on your CSS.
img {
opacity: 0;
}
.hovered {
opacity: 1;
}
Have you also considered fading using CSS Webkit?

Categories