I answered a question earlier to run a jQuery animation when a link is clicked. Then the poster asked quite a valid question which stumped me.
"How do you only run the animation on the 1st click"...
I thought this would be pretty simple, so I tried something like this:
clicked = true;
$('#hotel').click(function(){
if (clicked){
$('#Hotelbody').animate({width:'toggle'},1000);
$('#Hotelbody').fadeIn();
$('#Mealsbody').hide();
clicked = false;
}
});
which, in all fairness, runs the animation only on the 1st click. But then if I clicked off that menu item and onto "Meals" for example, and return to click "Hotels" the animation doesn't run at all. I have spent the whole morning trying to figure this out, and I am getting frustrated now - haha
Essentially, what needs to happen is while the user is on "Hotels" menu item do not run the animation again if he / she clicks "Hotels" menu item. But if the user ventures to another menu item and returns to hotels, then run the animation.
Please see FIDDLE as an example.
Steps to follow:
1. Click Hotel --> (Animation runs)
2. Click Hotel again --> (Animation doesn't run)[so far, so good]
3. Click Meals --> Then Click Hotels again --> (Animation will not run again)
Please let me know if I need to explain myself further?
Thoughts:
- Have jQuery look at css class :active and animate from that?
Can't be that hard, just check if the one that's clicked is currently visible
$('#Hotel, #Meals').on('click', function(){
var el = $('#'+this.id+'body');
if ( el.is(':visible') ) return false;
el.animate({width:'toggle'},1000)
$('#Mealsbody, #Hotelbody').not(el).hide();
});
FIDDLE
Another way using classes http://jsfiddle.net/gMha8/17/
$('.tabs_bar').on('click', '#hotel:not(.now)', function () {
$(this).addClass('now');
$('#Meal').removeClass('now');
$('#Hotelbody').animate({
width: 'toggle'
}, 1000);
$('#Hotelbody').fadeIn();
$('#Mealsbody').hide();
});
$('.tabs_bar').on('click', '#Meal:not(.now)', function () {
$(this).addClass('now');
$('#hotel').removeClass('now');
$('#Mealsbody').animate({
width: 'toggle'
}, 1000);
$('#Mealsbody').fadeIn();
$('#Hotelbody').hide();
});
Here's a stupid way to do it http://jsfiddle.net/gMha8/14/
function meal() {
$('#Mealsbody').animate({
width: 'toggle'
}, 1000);
$('#Hotelbody').animate({
width: 'toggle'
}, 1000);
$('#Mealsbody').fadeIn();
$('#Hotelbody').hide();
$('#hotel').off().on('click', hotel);
$('#Meal').off('click', meal);
}
function hotel() {
$('#Hotelbody').animate({
width: 'toggle'
}, 1000);
$('#Mealsbody').animate({
width: 'toggle'
}, 1000);
$('#Hotelbody').fadeIn();
$('#Mealsbody').hide();
$('#Meal').off().on('click', meal);
$('#hotel').off('click', hotel);
}
$('#hotel').off().on('click', hotel);
$('#Meal').off().on('click', meal);
Try this:
var lastClicked = null;
$('#hotel').click(function(e){
if (lastClicked != e.target){
$('#Hotelbody').animate({width:'toggle'},1000);
$('#Hotelbody').fadeIn();
$('#Mealsbody').hide();
}
lastClicked = e.target;
});
$('#Meal').click(function(e){
if (lastClicked != e.target){$('#Mealsbody').animate({width:'toggle'},1000);
$('#Mealsbody').fadeIn();
$('#Hotelbody').hide();
}
lastClicked = e.target;
});
http://jsfiddle.net/gMha8/22/
Try this
$('#hotel').click(function(){
$('#Hotelbody').animate({width:'toggle'},1000);
$('#Mealsbody').animate({width:'toggle'},1000);
$('#Hotelbody').fadeIn();
$('#Mealsbody').hide();
});
$('#Meal').click(function(){
$('#Mealsbody').animate({width:'toggle'},1000);
$('#Hotelbody').animate({width:'toggle'},1000);
$('#Mealsbody').fadeIn();
$('#Hotelbody').hide();
});
Demo
Related
I'm building a multi-level menu, where the submenu is being displayed with jquery.
It drops down when a main link is hovered, then slides up when the mouse leaves.
I want to stop the mouseleave action, when mouseover is active, but i can't stop the second event (animate->margin-bottom). I'm new to jquery, so i went through many questions and googled a lot, but i don't really understand what i'm supposed to do here. Any help will be greatly appreciated!
jQuery(".item-102 a").on('mouseenter', function() {
jQuery("#horizontal-menu").animate({"margin-bottom": "0px"}, 300);
jQuery("#submenu").slideDown("slow");
});
jQuery("#submenu").on('mouseleave',function() {
jQuery("#submenu").delay(2000).slideUp("slow");
jQuery("#horizontal-menu").delay(2000).animate({"margin-bottom": "+20px"}, 200);
});
jQuery("#submenu").on('mouseover', function() {
jQuery(this).stop();
});
Just try with:
jQuery("#submenu").on('mouseover', function()
{
jQuery(this).stop();
jQuery("#horizontal-menu").stop();
});
I've managed to do it, thanks everyone. Hsz's answer was good, but it didn't fully stop the event, so here's the solution:
function(){
jQuery(".item-102 a").on('mouseenter', function() {
jQuery("#horizontal-menu").animate({"margin-bottom": "0px"}, 300);
jQuery("#submenu").slideDown("slow");
});
var hover_off = false;
jQuery("#submenu").mouseover(function (){
hover_off = false;
});
jQuery("#submenu").mouseleave(function() {
hover_off = true;
setTimeout(myMouseOut, 1000);
});
function myMouseOut(){
if (hover_off == true){
jQuery("#submenu").delay(1000).slideUp("slow");
jQuery("#horizontal-menu").delay(1000).animate({"margin-bottom": "+20px"}, 200);
}
};
I'm having a small problem, i cant seem to solve.
I'm having a problem with the functionality of my animated function. When the div is clicked, it slides perfectly down, but when i click again on the div, it won't slide back up.
Thats the code i use....
$("#menu").click(function () {
if($(this).offset().bottom == -40) {
$(this).animate({'bottom': '0px'}, 1000);
}
else {
$(this).animate({'bottom': '-40px'}, 1000);
}
});
However, it works perfectly fine, when my div is positioned on top,left or right of my page, rather on bottom? Thats something i dont understand... but i must say, i'm rather new to Js.
I've set up a jsFiddle here... http://jsfiddle.net/JmLqp/438/
Any suggestions?
Thanks, B
Changed the JS to check for the div's bottom value, and animate from that. Fiddle
$("#menu").click(function () {
if($(this).css('bottom') == '-40px') {
$(this).animate({'bottom': '0px'}, 1000);
}
else {
$(this).animate({'bottom': '-40px'}, 1000);
}
});
It looks like you aren't getting the right value out of $(this).offset().bottom. You could do this instead:
var status = "up"
$("#menu").click(function () {
if(status == "up") {
status = "down"
$(this).animate({'bottom': '100px'}, 1000);
}
else {
$(this).animate({'bottom': '-30px'}, 1000);
status = "down"
}
});
I have this code which animates between divs sliding out. If an item is clicked, it's relevant content slides out. If another item is clicked, the current content slides back in and the new content slides out.
However,
var lastClicked = null;
var animateClasses = ['ale', 'bramling', 'bullet', 'miami-weisse'];
for (var i=0; i<animateClasses.length; i++) {
(function(animCls) {
$('.each-brew.'+animCls).toggle(function() {
if (lastClicked && lastClicked != this) {
// animate it back
$(lastClicked).trigger('click');
}
lastClicked = this;
$('.each-brew-content.'+animCls).show().animate({ left: '0' }, 1000).css('position','inherit');
}, function() {
$('.each-brew-content.'+animCls)
.animate({ left: '-33.3333%' }, 1000, function() { $(this).hide()}) // hide the element in the animation on-complete callback
.css('position','relative');
});
})(animateClasses[i]); // self calling anonymous function
}
However, the content sliding out once the already open content slides back is sliding out too quickly - it needs to wait until the content has fully slided back in before it slides out. Is this possible?
Here's a link to what I'm currently working on to get an idea (http://goo.gl/s8Tl6).
Cheers in advance,
R
Here's my take on it as a drop-in replacement with no markup changes. You want one of three things to happen when a menu item is clicked:
if the clicked item is currently showing, hide it
if something else is showing, hide it, then show the current item's content
if nothing is showing, show the current item's content
var lastClicked = null;
// here lastClicked points to the currently visible content
var animateClasses = ['ale', 'bramling', 'bullet', 'miami-weisse'];
for (var i=0; i<animateClasses.length; i++) {
(function(animCls) {
$('.each-brew.'+animCls).click(function(event){
if(lastClicked && lastClicked == animCls){
// if the lastClicked is `this` then just hide the content
$('.each-brew-content.'+animCls).animate(
{ left: '-33.3333%' }, 1000,
function() {
$(this).hide();
}).css('position','relative');
lastClicked = null;
}else{
if(lastClicked){
// if something else is lastClicked, hide it,
//then trigger a click on the new target
$('.each-brew-content.'+lastClicked).animate(
{ left: '-33.3333%' }, 1000,
function() {
$(this).hide();
$(event.target).trigger('click');
}).css('position','relative');
lastClicked = null;
}else{
// if there is no currently visible div,
// show our content
$('.each-brew-content.'+animCls).show()
.animate({ left: '0' }, 1000)
.css('position','relative');
lastClicked = animCls;
}
}
});
})(animateClasses[i]); // self calling anonymous function
}
Well, I'm pretty sure there are other more easy possibilities and I didn't have much time but here is a working jsfiddle: http://jsfiddle.net/uaNKz/
Basicly you use the callback function to wait until the animation is complete. In this special case it's the complete: function(){...}
$("document").ready(function(){
$('#ale').click(function(){
if ($('div').hasClass('toggled')){
$('.toggled').animate({ width: "toggle" }, { duration:250, complete: function(){
$('#alecont').animate({ width: "toggle" }, { duration:250 }).addClass('toggled');}
}).removeClass('toggled');
}else{
$('#alecont').animate({ width: "toggle" }, { duration:250 }).addClass('toggled');
}
});
$('#bramling').click(function(){
if ($('div').hasClass('toggled')){
$('.toggled').animate({ width: "toggle" }, { duration:250, complete: function(){
$('#bramcont').animate({ width: "toggle" }, { duration:250 }).addClass('toggled');}
}).removeClass('toggled');
}else{
$('#bramcont').animate({ width: "toggle" }, { duration:250 }).addClass('toggled');
}
});
});
I give a toggled class if a div is expanded. Since the animation on your page seems to be pretty much broken I think this would be a better way to do this. But remember: my code isn't really good. Just fast and it can be refactored. It's working tho..
Rather than using toggles, bind an on "click" handler to your ".each-brew" divs. In the handler, first hide content divs and then show the appropriate content when that animation completes. You can do that with either a promise or a callback. Something like this...
$(".each-brew").on("click", function (event) {
$(".each-brew-content").show().animate({ left: "0" }, 1000, function() {
// Get the brew name from the class list.
// This assumes that the brew is the second class in the list, as in your markup.
var brew = event.currentTarget.className.split(/\s+/)[1];
$(".each-brew-content." + brew).animate({ left: "-33.3333%" }, 1000, function() { $(this).hide(); });
});
});
I think an event and observer would do the trick for you.
set up the callback function on completion of your animation to fire an event.
the listener would first listen for any animation event and after that event is triggered listen for the completion event. when the completion event is fired execute the initial animation event.run method (or whatever you would want to call it)
Within the listener
on newanimationeventtriger(new_anim) wait for x seconds (to eliminate infinite loop poss) while if this lastevent triggers done == true{
new_anim.run();
}
I want if user moved the mouse for two seconds (Keep the mouse button for two seconds) on a class, show to he hide class. how is it? ()
If you move the mouse tandem (several times) on class, You will see slideToggle done as automated, I do not want this. How can fix it?
DEMO: http://jsfiddle.net/tD8hc/
My tried:
$('.clientele-logoindex').live('mouseenter', function() {
setTimeout(function(){
$('.clientele_mess').slideToggle("slow");
}, 2000 );
}).live('mouseleave', function() {
$('.clientele_mess').slideUp("slow");
})
Please try this below link Your Problem will solve
http://jsfiddle.net/G3dk3/1/
var s;
$('.clientele-logoindex').live('mouseenter', function() {
s = setTimeout(function(){
$('.clientele_mess').slideDown();
}, 2000 );
}).live('mouseleave', function() {
$('.clientele_mess').slideUp("slow");
clearTimeout(s)
})
Write your html like this
<div class="clientele-logoindex">Keep the mouse here
<div class="clientele_mess" style="display: none;">okkkkkkko</div></div>
Record when a timer is started and check if one exists before starting a new one:
window.timer = null;
$('.clientele-logoindex').live('mouseenter', function() {
if(!window.timer) {
window.timer = setTimeout(function(){
$('.clientele_mess').slideToggle("slow");
window.timer = null;
}, 2000 );
}
}).live('mouseleave', function() {
$('.clientele_mess').slideUp("slow");
})
Take a look at hoverIntent is a jquery plugin to ensure hover on elements.
I'm creating a feature content slider using jQuery and I have hit a few snags trying to get rid of the last few bugs. It is inspired by http://kleientertainment.com/ so check it out and you'll see what im going for. Any suggestions on achieving this effect even with totally new code would be helpful!
The idea is a simple div swap, but with custom animations for each slide that fire when it is loaded. It also MUST fade to black in between each transition, whether autoplay or clicked.
lets get to the code and bugs:
$(document).ready(function () {
//START SLIDES HIDDEN
$('.slide').css({
'position': 'absolute',
'display': 'none'
});
//RUN FIRST SLIDE
runSlideShow(1);
animation1_swap();
//AUTOPLAY FUNCTION
function runSlideShow(slideNumber) {
$('#slide' + slideNumber).fadeIn(1000).delay(10000).fadeOut(1000, function () {
if (slideNumber == 4) {
animation1_swap();
runSlideShow(1);
}
if (slideNumber == 3) {
animation4_swap();
runSlideShow(4);
}
if (slideNumber == 2) {
animation3_swap();
runSlideShow(3);
}
if (slideNumber == 1) {
animation2_swap();
runSlideShow(2);
}
});
//NAVIGATION BUTTONS
$('#bullet1').click(function () {
$('.slide:visible').stop(true, true).fadeOut(1000, function () {
animation1_swap();
runSlideShow(1);
});
});
$('#bullet2').click(function () {
$('.slide:visible').stop(true, true).fadeOut(1000, function () {
animation2_swap();
runSlideShow(2);
});
});
$('#bullet3').click(function () {
$('.slide:visible').stop(true, true).fadeOut(1000, function () {
animation3_swap();
runSlideShow(3);
});
});
$('#bullet4').click(function () {
$('.slide:visible').stop(true, true).fadeOut(1000, function () {
animation4_swap();
runSlideShow(4);
});
});
}
});
CSS info: .slide sets the dimensions, and #slideX are the individual background images for each. #bulletX are the nav buttons.
Also, the animationX_swap() are the animations specific to that slide. They live in another file and would have made this post way too long.
The bugs:
Right now, the autoplay function is great, you can watch it all day and not see a hiccup. The trouble comes when the nav buttons are used, particularly #bullet1. If i click #bullet1, then go to 2, then back to 1, the autoplay seems to be sped up as the slide fades out before it is supposed to. I am a total beginner but I made it this far, can anyone help me clean this up and essentially reimagine http://kleientertainment.com/ 's slider?
Just discovered jQuery cycle plugin http://malsup.com/jquery/cycle/ from another post.
I remade my slider with that and it preforms exactly as needed. Good stuff!