I just coded a menu that has an animation in javascript. The script works as it should but I don't like that if you navegate throught the items from up to down, the menu gets really buggy and the texts start to display like crazy. A possible solution is, that when the mouse enters to a list item, it has to have a certain delay for the animation to start (for example, you must have the mouse there 3 seconds, if not, nothing happens). setTimeout won't do it, because it will execute the animation anyway. I am wondering if there is a work around this, because i can't come up with any.
this is the code that does the animation:
$( '.menu li a' ).hover( function(){
var el = $(this);
var numero = el.parent().index();
el.animate({
'height': height[numero]+'px'
}, 'slow');
}, function(){
$(this).animate({
'height': 0
}, 'slow');
});
jsfiddle here
I am trying to attempt this without using css Transitions. Thank you very much!
Try to stop the previous animation queue by using .stop(),
$( '.menu li a' ).hover( function(){
var el = $(this);
var numero = el.parent().index();
el.stop().animate({
'height': height[numero]+'px'
}, 'slow');
}, function(){
$(this).stop().animate({
'height': 0
}, 'slow');
});
DEMO
Related
I'm foolin around with the jquery hover functionality. the current code snippet looks like this:
$leftColumn.children().first().hover(
function(event) {
var $this = jQuery(this);
$this.css({
'background-color': '#505050'
}).parent().stop()
.animate(
{
'z-index': '999',
width: '220px'
},
{
duration: '1000'
}
);
},
function(event) {
var $this = jQuery(this);
$this.parent().stop()
.animate(
{
width: '38px',
'z-index': '1'
},
{
duration: '1500',
complete: function() {
$this.css({
'background-color': 'transparent'
});
}
}
);
}
);
What this basically does is increasing the width of a div (which is position absolute) to overlay another div.
I choosed to use jQuerys animate() functionality instead of CSS3s transition because I want to trigger a callback whenever the closing (decreasing the width again) animation is done.
My problem now is, that I want to delay the closing animation for 2 seconds (and yes I know about the delay() vs setTimeout() discussion) which worked fine with setTimeout(). However as the animation is timed out for the given duration it will run, even if I enter the hoverable area again. This of course makes sense as the stop() only triggeres while an animation is on the go, which is not the case if it is timed out.
How can I make this thing work (stop the closing animation when reentering the hoverable area) and still keep a timeout / delay before decreasing the width on "hover leave"?
So
I am trying to build some navigation using jquery transit
The opens/slide down navigation is working fine. It sets the child ul to display block and then runs the animation/transition.
The issue is occurring when closing the navigation item. The ul gets hidden immediately diespite being written inside the callback. I've also added a console log of 'animation ended' once the transition has finished and this is firing at the right time, so not sure why the ul is being hidden immediately.
The jquery/js looks like this:
var dropDown = (function(){
var mainNav = $('#mainNav');
var navA = mainNav.find('li a');
var navUL = mainNav.find('ul');
var iconAll = mainNav.find('i');
navUL.transition({
'max-height': '0px',
'height': '0px',
'overflow': 'hidden',
'display': 'none'
});
navA.on('click',function(){
var nextUL = $(this).next();
var icon = $(this).find('i');
var nextULHidden = nextUL.css('display') === 'none';
if(nextULHidden) {
nextUL.css('display','block').transition({
duration: 1000,
'height': 'auto',
'max-height': '1000px',
easing: 'ease-in'
});
$(this).addClass('active');
icon.removeClass('fa-chevron-down').addClass('fa-chevron-up');
console.log('hidden');
}else if(!nextULHidden){
nextUL.transition({
duration: 1000,
'height': '0px',
'max-height': '0px',
easing: 'ease-in',
complete: function(){
nextUL.css('display','none');
console.log('animation ended');
}
});
$(this).removeClass('active');
icon.removeClass('fa-chevron-up').addClass('fa-chevron-down');
console.log('visible');
}else{
console.log('some error');
}
return false;
});
}());
And I have a fiddle here that can be tinkered with: http://jsfiddle.net/lharby/o5w8ebu8/2/
I've tried various combinations of using css visibility, jquery show() and hide() functions, but each time the ul vanishes as the transition starts (on click effectively). And I've tested Chrome, Firefox and Safari just in case there were any anomalies.
I believe the callback is firing at the correct time (after 1000 milliseconds) the problem is that the transition animation isn't working.
Changing to 'height': 'auto' on the shrinking transition seems to achieve the effect you are after. Though I can't say I really know why.
I have a simple jQuery code which swaps two images by hiding one and displaying the other, I'm seeking to swap the images using a fade in fade out effect, but since the two images aren't lying on top of each other I cant simply fade the top image resulting on showing the bottom one,
I want to fade the first image then set the css display property to none then show the second image with 0 opacity and gradually set the second images opacity to 100. But when I add the code which fades the images, it doesn't work and the display none doesn't wait for the fade to finish. How can I make the functions wait for the one before to finish?
$('.thumbs').hover(
function() {
console.info('in');
$(this).children('.first').css('display','none');
$(this).children('.second').css('display','block')
},
function() {
console.info('out');
$(this).children('.second').css('display','none');
$(this).children('.first').css('display','block')
}
);
HTML Code:
<div class='thumbs'>
<div class='first'><?php the_post_thumbnail()?></div>
<div class='second'><?php MultiPostThumbnails::the_post_thumbnail(get_post_type(), 'secondary-image');?></div>
</div>
1) delay() method allows us to delay the execution of functions that follow it in the queue.
http://api.jquery.com/delay/
$( "#foo" ).slideUp( 300 ).delay( 800 ).fadeIn( 400 );
2) use callbacks
$("#divId1").animate({opacity:.1},1000,function(){
$("#divId2").animate({opacity:.1},1000);
});
Like so:
setTimeout(function() {
console.log('out');
$(this).children('.second').css('display', 'none');
$(this).children('.first').css('display', 'block');
}, 1000);
I have not tested but this should do the job:
$('.thumbs').hover(
function(){
var $that = $(this);
$(this).children('.first').fadeOut(1000, function(){
$(this).css('display','none');
$that.children('.second').fadeIn(500);
});
}
,
function(){
var $that = $(this);
$(this).children('.second').fadeOut(1000, function(){
$(this).css('display','none');
$that.children('.first').fadeIn(500);
});
}
);
Try
$('.thumbs').hover(
function() {
var second = $(this).children('.second');
$(this).children('.first').fadeOut(1000, function(){
second.fadeIn(1000,function(){});
});
},
function() {
var first= $(this).children('.first');
$(this).children('.second').fadeOut(1000, function(){
first.fadeIn(1000,function(){});
});
}
);
Working Fiddle
I have a button that I want to click (in my case this is '.circle'). When I click it, I want the #data div to fade in then animate with a 'margin-top:50px'. Then when the user clicks the toggle button the second time it animates to 'margin-top:0px' then fades out.
However the problem I have run into is that when I click the toggle the third time I would expect it to run the first function again. But instead it does something weird and resets to a margin-top of 50px before the first function is run again.
I would really appreciate some help with this. Here is a JSFiddle I whipped up with identical code and you will see the problem i'm having after clicking it multiple times. Also another problem was when you click it for the first time it doesn't work, but works on the second click.
http://jsfiddle.net/sN8Tn/
Ill also post the bit of jquery below:
$(".button").click(function(){
$(".button").toggle(
function(){
$("#showme").fadeIn(500,
function(){
$("#showme").animate({ "margin-top" : "50px" }, 500, 'linear');
}
);
},
function(){
$("#showme").animate({ "margin-top" : "0px" }, 500, 'linear',
function(){
$("#showme").fadeOut(500);
}
);
});
});
Remove the .click() function. The click is implied with the .toggle() function. jQuery .toggle() jsFiddle
$(".button").toggle(
function() {
$("#showme").fadeIn(500, function() {
$("#showme").animate({
"margin-top": "50px"
}, 500, 'linear');
});
}, function() {
$("#showme").animate({
"margin-top": "0px"
}, 500, 'linear', function() {
$("#showme").fadeOut(500);
});
});
I've run into a small problem, Ive got a page full of anchor tags and when 1 of them is selected an animation begins, my only problem right now is that I havent defined the anchor tag as (this) so when a series of anchors are selected each of them perform the animation, im not sur right now how I can change the a tag to this though?
My code so far is:
$('a').bind('click', function(e){
$ajax = $('<div id="ajax"></div>');
$ajax.prependTo('#container');
$('html, body').animate({ scrollTop: 0 }, 'fast', function(){
$ajax.animate({ height: 300 }, 'slow', function(){
$preloader = $('<div id="preloader"></div>').hide();
$preloader.prependTo('#ajax').fadeIn('normal');
});
});
e.preventDefault();
});
you want to add an id to your anchor tag like this
<a id="myTag" href=""></a>
Then you can access it like this
$('#myTag').bind(...
You should only use an id once per page (meaning that every id is unique, not that there can only be 1 id per page).
Here's some more info on the id-selector from Jquery and more selectors in general
You do not use var keywords. This is bad, as all variables you create this way are in the global scope overwriting each other
$('a').bind('click', function(e){
var $ajax = $('<div></div>').prependTo('#container');
$('html, body').animate({ scrollTop: 0 }, 'fast', function(){
$ajax.animate({ height: 300 }, 'slow', function(){
$('<div></div>').hide().prependTo($ajax).fadeIn('normal');
// you can refer to $ajax here! --^^^^^
});
});
e.preventDefault();
});