jQuery new divs won't animate with $(document).on - javascript

So, I had an animation function. It worked. You hover over some squares, they leave a little trail and then fade back:
$(".square").bind("webkitAnimationEnd mozAnimationEnd animationend", function(){
$(this).removeClass("squareAnim");
});
$(".square").hover(function(){
$(this).addClass("squareAnim");
});
.squareAnim {
animation-name: changeColor;
animation-duration: 4s;
}
#keyframes changeColor {
0% {background-color: rgb(5, 5, 5);}
25% {background-color: rgba(255, 5, 20);}
50% {background-color: rgba(20, 5, 255);}
100% {background-color: rgb(5, 5, 5);}
}
Later, I decided I needed to add/remove squares based on the page size. I got help here.
Welp, I had to change the animation function because it's bind and won't work on new divs. I researched and tried different functions, and this is where I'm at now:
$(document).ready(function(){
$(document).on("webkitAnimationEnd mozAnimationEnd animationend", ".square", function(){
$(this).removeClass("squareAnim");
});
$(document).on("hover", ".square", function(){
$(this).addClass("squareAnim");
});
});
But, it's not working. I don't know if $(document).ready is redundant (it was my attempt at delegation) but it still doesn't work with or without it. Is there something I'm missing?
Edit jsfiddle

You have to rebind the events when you create the elements (i.e. onresize). It will not propagate to newly created elements if you just bind it once onready.
Also, onhover is deprecated (removed in jQuery 1.9) and should be replaced with onmouseenter and onmouseleave.
From jQuery's docs:
Deprecated in jQuery 1.8, removed in 1.9: The name "hover" used as a shorthand for the string "mouseenter mouseleave". It attaches a single event handler for those two events, and the handler must examine event.type to determine whether the event is mouseenter or mouseleave. Do not confuse the "hover" pseudo-event-name with the .hover() method, which accepts one or two functions.
$(window).on("resize", function() {
multiplyNode(contain.querySelector('.square'), canAdd(), false);
$(document).on("webkitAnimationEnd mozAnimationEnd animationend", ".square", function() {
$(this).removeClass("squareAnim");
});
$(document).on("mouseenter", ".square", function() {
$(this).addClass("squareAnim");
});
}).resize();
Updated fiddle

Related

jQuery FadeIn / FadeOut Methods not working

I want to fade the image on hover.
Why does this not work?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#lightbulb").hover(function(){
$("#lightbulb").fadeOut('fast');
},function(){
$("#lightbulb").fadeIn();
});
});
</script>
Other jQuery methods like CSS styling and changing image sources are working.
You cannot place the fadeOut() effect at the same element you add the hover() to.
fadeOut() sets the Element to "display: none;" and removes it from the DOM.
So a $fadeIn() effect can never take place, because the element with the $hover() targeted is gone.
You need to target a parent container with hover() and fadeIn() and fadeOut() the inner elements. That should work.
$("#parentbulb").hover(function(){
$("#lightbulb").fadeOut('fast');
},function(){
$("#lightbulb").fadeIn();
});
You could use css instead of jQuery if that works. When you fadeOut the element, the hover exit event is fired, so it will just keep toggling between the states the way you have it. Here is a fiddle with an example of hiding/showing on hover. Basically you do like
#elem {
opacity: 1;
transition: opacity: 0.2s;
}
#elem:hover {
opacity: 0;
}
on whichever element you want to hide.

"animationend" does not fire sometimes

I have a CSS animation that gets applied to a HTML element with a CSS class. I also have an event listener attached to the animationend (it's a modern Windows app so the browser is IE11 only). What I'm seeing is that sometimes the event gets fired and sometimes it doesn't. Regardless of the event firing I can always see it visually animating. It looks like some kind of race condition to me.
I have searched the web trying to understand what could cause this event to not get fired but I haven't found any satisfying results. I found the following on MDN:
Note: The transitionend event doesn't fire if the transition is aborted because the animating property's value is changed before the transition is completed.
UPDATE1: transitionend has nothing to do with animationend so this info is unrelated.
I'm not sure if the same is applicable for CSS animations. Does anyone have any ideas as to what can cause this? If there was any event that could detect that an animation was aborted that could also be a useful workaround.
UPDATE2: The current workaround that I'm using:
element.addEventListener("animationstart", function () {
setTimeout(function () {
// do stuff
}, animationDuration);
});
Is it possible that your animations aren't ending?
Check the documentation for the animationcancel event:
https://developer.mozilla.org/en-US/docs/Web/Events/animationcancel
However, it looks like browser support may be spotty ("onanimationcancel" in HTMLElement.prototype returns false for me in Chrome 67).
It seems that using a setTimeout hack may be necessary for the time being.
You can use this function
function onAnimationEnd(element, handler) {
//- Create local variables
var events = 'animationend transitionend webkitAnimationEnd oanimationend MSAnimationEnd webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd';
//- Bind event to element
$(element).on(events, handler)
//- Return received element
return element
}
This function binds an event when both animation or transition ends.
Also make sure that the animated element is not being deleted or moved while the animation is running.
With IE11, you can't necessarily assume that the JS event binding will occur before the CSS animation starts or ends. This type of issue is intermittent, and frequency/onset will depend on certain factors.
If the CSS animation-duration is low and the animation starts immediately after the stylesheet is ready, then it's possible that the JS event binding will not be applied in time
A solid workaround I've found is to use JS to invoke the CSS animation using a className. i.e., Only apply the CSS animation-name property when the className has been applied via JS.
FWIW, this is still a problem. In some cases (so far I've only reproduced it on mobile) certain elements with a well-defined animation don't always fire the animationend event.
EDIT: Turns out the issue is with animating after content. Safari just doesn't reliably handle it. I ended up making a distinct strikethrough div and animating that.
function animateCSS(element, animationName, callback) {
const node = typeof element == 'string' ? document.querySelector(element) : element;
node.classList.add('animated', animationName);
node.onanimationend = handleAnimationEnd;
console.log('animateCSS', node, animationName);
function handleAnimationEnd() {
console.log('handleAnimationEnd', node, 'remove:', animationName);
node.classList.remove('animated', animationName);
node.onanimationend = null;
if (typeof callback === 'function') callback(node);
}
}
.strike {
color: #e402b3;
position: relative;
}
.strike:after {
content: ' ';
position: absolute;
top: 50%;
left: 2%;
height: 2px;
background: #e402b3;
animation: strike 0.7s linear 0s 1 forwards;
-webkit-animation: strike 0.7s linear 0s 1 forwards;
}
#keyframes strike {
0% {
width: 0%;
color: #000;
}
100% {
width: 96%;
color: #e402b3;
}
}
#-webkit-keyframes strike {
0% {
width: 0%;
color: #000;
}
100% {
width: 96%;
color: #e402b3;
}
}

mouse enter event is not working properly

Hi I am trying to hide a div on mouse enter on body, it is not working properly, the div I am trying to hide, will hide and comes again. Checkout this fiddle
Here is my code:
JS:
$(document).mouseenter(function() {
$('.jadu').hide(10);
}).mouseout(function(){
$('.jadu').show(10);
});
HTML:
<div class="jadu"></div>
CSS:
*{padding:0px;margin:0px;}
.jadu{
position:fixed;
width:100%;
height:100%;
background-color:#555;
opacity:0.8;
display:block;
z-index:3;
}
body{
background:red;
}
this is fiddle link: Fiddle
Simply use the mouseleave event.
$(document).mouseenter(function() {
$('.jadu').hide(10);
}).mouseleave(function(){
$('.jadu').show(10);
});
JS Fiddle
When you use mouseout on an element and there is a child in it (document > .jadu) the mouseout event is triggered when you hover the .jadu element (child).
Using mouseleave, this event won't be triggered when you hover a child of document.
See the fiddle;
http://jsfiddle.net/xibalbian/UaJZr/
$(document).mouseenter(function() {
$('.jadu').hide(10);
}).mouseleave(function(){
$('.jadu').show(10);
});
If the matched elements have no child element, both mouseout() and mouseleave() events are work exactly same.
If the matched elements have child element, both mouseout() and mouseleave() events are work different in the way of “event bubbling”.
You can see this page which explains clearly -> Difference between mouseout() and mouseleave()
Use mouseleave event. jsfiddle
$(document).mouseenter(function() {
$('.jadu').hide(10);
});
$(document).mouseleave(function(){
$('.jadu').show(10);
});
Visit: JsFiddle
/* Do not use equal time in hide and show: */
$(document).mouseenter(function() {
$('.jadu').hide(100);
}).mouseout(function(){
$('.jadu').show();
});

jQuery .focus() causes page to jump

I have a function that should scroll a user back to a search input at the top of the page, and then place focus on it (so the cursor is blinking). For some reason, it seems to apply the focus to the search input first. This creates a very quick jump/spazzy movement of the page to the search bar, jumps back to the bottom, and then scrolls up slowly.
The Javascript:
function goToSearch(){
$('html,body').animate({scrollTop: $('#search').offset().top},'medium');
$('#search').focus()
}
The HTML:
<input type="text" id="search" placeholder="search">
...
Search
I've tried setting .delay() functions to no avail; it seems to always apply the .focus() first. Why is this happening?
"Why is this happening?"
The animation effect is asynchronous. That is, the .animate() function returns immediately after "scheduling" the animation (so to speak) and execution continues immediately with the next statement - in your case, the .focus() statement. The actual animation will take place after the current JS completes.
Fortunately the .animate() method provides an option for you to pass a callback function that will be called when the animation is complete, so you can do the focus within that callback function:
$('html,body').animate({scrollTop: $('#search').offset().top},'medium', function(){
$('#search').focus();
});
You should call the focus function when the animation is complete, like so:
function goToSearch(){
$('html,body').animate({scrollTop: $('#search').offset().top},'medium',function(){
$('#search').focus();
});
}
If you found this question like me, you were probably looking for a CSS related issue coupled with the js focus() and you might think you're out of luck. Well, think again - the good news is that there IS a way to have a callback when a CSS animation or transition ends and then fire your event.
You can make use of jQuery's one method and use either webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend for transitions or webkitAnimationEnd oanimationend msAnimationEnd animationend for animations.
An example:
JS:
var myButton = $('#button'),
myBox = $('#box');
myButton.click(function () {
myBox.addClass('change-size');
myBox.one('webkitAnimationEnd oanimationend msAnimationEnd animationend',
function(e) {
// code to execute after animation ends
myBox.removeClass('change-size');
});
});
CSS:
.box {
width: 100px;
height: 100px;
background: hotpink;
}
#keyframes growBox {
to {
width: 300px;
height: 200px;
}
}
.change-size {
animation: growBox 3s linear 0s 1 normal;
}
The solution is not mine, I just found it after a couple of wasted hours, and I'm posting it in case you find this question first.
Source: http://blog.teamtreehouse.com/using-jquery-to-detect-when-css3-animations-and-transitions-end

Jquery - bind/unbind hover script, small bit of code, not sure what to do

I've created DIV.cb-toggle, when the user hovers over this div, it animates to Orange, when they hover off of this div, it animates back to gray, when the user clicks this div, it animates to blue, telling the user that it's been selected. So when it's NOT selected, it has mouseenter mouseleave animations, but when it's selected i want to unbind mouseenter mouseleave, I DO NOT want the hover event to work when it's been selected, only when it's not selected. What's the best way to do what i'm trying to accomplish? I came up with the code below but i'm pretty sure this is a horrible way to do it and i don't know what to do. thank you so much for any help.
my code:
$('.cb-toggle').toggle(function() {
$(this).animate({"background":"blue", "color":"#fff;"});
$(".cb-toggle").unbind("click.myfadee");
}, function() {
$(this).animate({"background":"gray", "color":"#fff;"});
$('.cb-toggle').trigger('mouseenter');
});
});
and I'm calling this bind:
$(".cb-toggle").bind("click.myfadee", function(){
$(".cb-toggle").mouseenter(function() {
$(this).animate({"background":"orange", "color":"#fff;"});
}).mouseleave(function() {
$(this).animate({"background":"gray", "color":"#fff;"});
});
});
I need to keep the background color animation, and i'm not using jquery UI so i cannot animate between classes.
You know, with a little bit of CSS, this could be achieved easily.
CSS
.cb-toggle {
background-color: gray;
color: #fff;
}
.cb-toggle:hover {
background-color: orange;
}
.cb-toggle.selected {
background-color: blue;
}
HTML
Toggle This​
jQuery
$('.cb-toggle').click(function() {
$(this).toggleClass('selected');
});​
demo
this is just an example, you could extend it to do your animation. You may want this link too
With animation demo

Categories