Event handler keeps on calling earlier than animate function - javascript

Just to see how event bubbling works I created many div controls, one into another and so on and finally attached click event to all the div which make div to flash whenever it is clicked. I was hoping that one div will flash then another and like this it will bubble up to the parent but all the div's are flashing at the same time.
Why doesn't one event handler complete before calling another one? Does animate function is doing something? Because it doesn't happen normally, I had always noticed that only after completing one event handler another one gets called.
Here is my js:
$("div").on("click", function (e) {
$(this).animate({ backgroundColor: "red" }, 400, "swing", function () {
$(this).animate({ backgroundColor: "white" }, 400, "swing")
})
})
Here is Html:
<div><div><div><div><div><div><div>
</div></div></div></div></div></div></div>

From Jquery http://api.jquery.com/animate/
Animation Properties and Values
All animated properties should be animated to a single numeric value, except as noted below; most properties that are non-numeric cannot be animated using basic jQuery functionality (For example, width, height, or left can be animated but background-color cannot be, unless the jQuery.Color plugin is used). Property values are treated as a number of pixels unless otherwise specified. The units em and % can be specified where applicable.
There is a plugin mentioned from that page to allow animating the background color. Also in your code you may or may not want to incorporate:
e.stopPropogation();
That will stop the div event from bubbling up.
You could:
$("div").on("click", function (e) {
$(this).css({backgroundColor: "red", opacity: 0})
$(this).animate({ opacity: 1 }, 400, "swing", function () {
$(this).css({backgroundColor: "white", opacity: 0})
$(this).animate({ opacity: 1 }, 400, "swing")
})
})
It will have a different effect though, the div will disappear and reappear red, then disappear and reappear white.
If you are just trying to pause the propagation then restart at the end of the annimation you could just retrigger the event on the parent element;
$("div.animate").on("click", function (e) {
e.stopPropagation();
$(this).animate({ backgroundColor: "red" }, 400, "swing", function () {
$(this).animate({ backgroundColor: "white" }, 400, "swing", function(){
$(e.target.parentElement).trigger(e.type);
})
})
})
To make only certain divs animate just add a class to them "animate" for instance and then attach the handler to divs with animate only and any other div will propogate the click automatically with your animation classed divs stopping the propogation, animating and when finished passing up the DOM tree.

Related

Animation not being made jquery (backgroundColor)

I'm having a problem where I'm making a function in JavaScript (JQuery):
$('.login').click( function() {
$('#login-container').animate({
left: 0
}, 300, "swing", function(){
$('#login-container').animate({
backgroundColor: 'rgba(0,0,0,0.4)'
}, 2000, "swing");
});
});
Whereas "login" is a button and login-container is a big div which contains a form which people can use to login.
I'm trying to make the giant container that slides over the page only turn its background color to lower the website's exposure but it's working and as far as I know, the code is correct.
The first animation happens but the second one (referring to the backgroundColor) doesn't even start at all.
Thanks in advance
EDIT:
I've simplified my code to see if it was a problem of my syntax or JS simply not applying this animation:
$('.login').click( function() {
$('#login-container').animate({
backgroundColor: 'rgba(0,0,0,0.4)'
}, 2000, "swing");
});
And the element does not have its background-color applied, for some reason.
I don't actually get what you're trying to say here, but if you want to toggle that animation you can use $.toggle() of jquery after the user clicks.
If you want to animate this stuff, look at this documentation provided by jQuery
jQuery Animation

Hover over div sometimes doesn't change back to original color

I have a list of divs, each with a different background color. When I hover over any of them, I want it to change to gray, then back to its original color when my mouse leaves the element. Here is the code I have used to do so:
var originalColor;
$('.div-class-name').hover(
function() {
originalColor = $(this).css('background-color');
$(this).animate({
backgroundColor: 'rgb(125,125,125)'
}, duration);
}, function() {
$(this).animate({
backgroundColor: originalColor
}, duration);
}
);
It animates the background change as it should. However, occasionally an element will stay faded to gray even after I mouse out, which makes me think that originalColor is being modified between when we mouse over and when I mouse out. Is there a way to set the variable in the first function and get its value in the second function without allowing it to be corrupted by hovering over another element while the first is still transitioning? (This is my assumption for why sometimes a color won't fade back to its original)
$(this).css('background-color') is accessing the color of the element the moment you hover over it. If you hover over it while it is stil doing the animation, the color will be somewhere between COLOR_A and COLOR_B.
You want to store the initial value so that you can re-use it, regardless of the current state of the animation.
Option 2: see #Tushar Gupta's answer about using .stop to stop the animation immediately. The color can instantly snap to the "destination" of the animation, using .stop(true, true).
Option 3: Consider keeping your "styles" inside your "stylesheets" - which is more logical. You can also use transitions to perform the animation, even without using javascript:
a {
color: #F00;
transition: color 0.5s linear;
}
a:hover {
color: #000;
}
Note that javascript animations do still have their uses, however. but for simple color animations, CSS should be sufficient.
Use .stop( [clearQueue ] [, jumpToEnd ] )
Stop the currently-running animation on the matched elements.
$('.div-class-name').hover(function () {
originalColor = $(this).css('background-color');
$(this).stop(true, true).animate({
backgroundColor: 'rgb(125,125,125)'
}, duration);
}, function () {
$(this).stop(true, true).animate({
backgroundColor: originalColor
}, duration);
});

jQuery hover stuck

When I hover over an img which fades to another img and sroll off too fast, the fadeOut gets stuck and the fade stays. I've tried the .stop() as I've seen in other responses, but still won't work. Is there something else I can put instead of the .stop()?
<div class="grid big-square">
<a href="#"><img id="image2" src="img/fade/creo.png">
<img id="image1" src="img/creo.jpg"></a>
</div>
<script>
$("#image1").mouseenter(function () {
$(this).stop(true, true).fadeOut(1000);
});
$("#image2").mouseleave(function () {
$("#image1").stop(true, true).fadeIn(500);
});
</script>
I seem to remember having a similar problem when I was creating this website.
The solution is to use a combination of .hover() and .stop() to ensure that only one animation is running at a time, which I think you have. Also ensure that the mouseover image is on top of the other image, and just fade that one in and out. The image fading out gets 'stuck' because at some opacity the .mouseleave() stops firing and the .mouseenter() starts firing on the other image.
Something like:
$$ = $("#image1");
$$.hover(function () {
$$.stop().animate({
opacity: 0
}, 1000);
}, function () {
$$.stop().animate({
opacity: 1
}, 1000);
});
#image1 must be above #image2 for this to work, #image1 fades out to 'reveal' #image2 behind it. The code uses .animate() rather than .fadeIn() and .fadeOut() but the effect is the same.
Edit- to fade in another div after the end of the fadeoout animation use the complete call back of the animate function.
Something like:
$$ = $("#image1");
$$.hover(function () {
$$.stop().animate({
opacity: 0
}, 1000);
}, function () {
$$.stop().animate({
opacity: 1
}, 1000, function() {
$("#finalDiv").animate({ opacity: 1, 500 });
});
});
#finalDiv needs to be after the 2 <img />s in your html to appear above them.
I'm not sure how you're trying to accomplish this but I do know how it should be done.
Try this http://jsfiddle.net/xy5dj/
Make sure to listen for both events on the same element (preferably a wrapper element).
Take note that fadeOut actually removes the element from the rendered content (display: none) making sure that the mouse events won't fire on that element.
Side note:
A dirty trick that I used once (if you have to do this then you're doing something wrong) is to clear the style of the element after animation using the callback ability of the animate function i.e.
$('el').animate({opacity:0}, 500, function(){$(this).attr('style', '')});
fiddle
You should use the animation/transition in form:
.fadeTo( duration, opacity, complete )
where complete is callback function.

Make Image Grow Larger On Press And Toggle

On a website, I have a list of news articles mentioning a certain thing. I want the articles to be able to be pressed, and when they are, the image source will switch with the image source of the actual article, and the image will grow to an arbitrary size. When you click the image again, it should go back to normal. I also want it to set itself to be absolutely positioned or something that way it doesn't push elements out of its way when it grows.
I guess my first question would be, is there already a code snippet or easy implementation of this or something similar? I have not been able to find one.
Second, I am in the process of making my own, and for whatever reason, when the page loads, every image just fades to disappearing without anything being pressed. Here is my code so far...
$(".newsCover").toggle(function () {
$(this).animate({
width: "auto",
height: "1000px"
}, 1500);
}, function () {
$(this).animate({
width: "auto",
height: "300px"
}, 1500);
});
Can anyone tell me what is wrong with it and how to fix it? I have a feeling its just something really stupid...
Thanks so much!
The .animate() method allows us to create animation effects on any
numeric CSS property.
All animated properties should be animated to a single numeric value, except as noted below;
http://api.jquery.com/animate/
However, you can hack it by determining the auto height/width as a hard number:
JavaScript jQuery Animate to Auto Height
The toggle function that you are using was deprecated in 1.8, and removed in 1.9, see here: http://api.jquery.com/toggle-event/ In v 1.9+, the toggle function now simply hides the element.
With no parameters, the .toggle() method simply toggles the visibility
of elements
The parameters that can be passed to the new toggle function can be found here: http://api.jquery.com/toggle/ With the new toggle function, you are unable to run the .animate() function within it. To achieve what you're trying to do, you could do something like:
$(".newsCover").click(function() {
if($(this).height() > 300) {
$(this).animate({
width: "auto",
height: "1000px"
}, 1500);
}
else {
$(this).animate({
width: "auto",
height: "300px"
}, 1500);
}
});

jquery .animate() - this code sort of does what i want

I am trying to make a div slide down when the mouse moves over another div just above it. Basically the div above it is just the trigger that makes the div slide down. Mouseover of .trigger makes .slidedown expand, and mouseout of .slidedown makes itself slide back up. Here's the code i have so far:
$(document).ready(function() {
$('.slidedown').hide();
//When mouse rolls over
$('.trigger').mouseover(function(){
$('.slidedown').stop().animate({
height: ['toggle', 'swing'],
}, 600, function() {
// Animation complete.
});
});
//When mouse is removed
$('.slidedown').mouseout(function(){
$('.slidedown').stop().animate({
height:'0px'
}, 600, function() {
// Animation complete.
});
});
});
This works, but there are just two teaks i need help with. Firstly, after mouseout and the .slidedown div slides up and disappears, if i then mouse over the .trigger div again, nothing happens. It should make the .slidedown move down again. I need it to every time keep working. I tried removing the .stop() but it still doesn't work.
Also can i make it also slide back up if the mouse moves out of .trigger but only if it isn't moving out of .trigger into .slidedown? This is so incase the user doesn't move the mouse into .slidedown, it would remain forever which isn't good. Or just have a time limit that it can remain expanded if the mouse doesn't move over .slidedown.
Second, is there a way to make a delay of around 1 second between mouseout and the div sliding back up? Thanks for your help!
You might try using the jQuery hover event. For the delay, you can put the closing animation in setTimeout:
$(document).ready( function(){
$('.trigger').hover( function(){ // enter animation
$('.slidedown').stop(true,true).animate({
height: ['toggle', 'swing'],
}, 600, function() { /* animation done */ });
}, function(){ // leave animation
setTimeout( function(){
$('.slidedown').stop(true,true).animate({
height: '0px',
}, 600, function() { /* animation done */ });
}, 1000 );
});
});
You might also look into the hoverIntent plug-in for more nuanced control over the mouseenter/mouseleave behavior, including timing.
I think you'll find that setting a numerical height in $('.trigger').mouseover() may help the animation be repeatable. FYI, you can set an integer number for something like height or width in jQuery and it will automatically set the unit to px for you.
As Ken pointed out, setTimeout is useful for a delay in code, but keep it in your $('.slidedown').mouseout() event or the slideown div will hide after you mouseout of the trigger div instead of when you leave the slidedown div as you specified.

Categories