disable link temporarily during quickflip - javascript

I am using on my site the plugin Quickflip with tabs on my site .
However if by exemple I click too fast on var2 and then var1 there is a bug.
That is why I am trying to put a timeout of 1s on each click of the tab so that it would wait for the flip to do.
Here is how I call the quickflip function (and tab)
$('document').ready(function () {
$('#flip-container').quickFlip();
$('#flip-navigation li a').each(function () {
$(this).click(function () {
$('#flip-navigation li').each(function () {
$(this).removeClass('selected');
});
$(this).parent().addClass('selected');
var flipid = $(this).attr('id').substr(4);
$('#flip-container').quickFlipper({}, flipid, 1);
return false;
});
});
});
Is there a solution to this please ?

I try to test your code and find out the problem that you mentioned.
[EDIT]
You want tabs can't be clicked until flip animation stop. I check the quickflip lib implementation and find out when div is flipping all the flip content display style will be set to "none". So I implement a "is animating" checking function.
Try this:
$('#flip-navigation li a').each(function () {
$(this).click(function () {
$('#flip-navigation li').each(function () {
$(this).removeClass('selected');
});
$(this).parent().addClass('selected');
var flipid = $(this).attr('id').substr(4);
var isAnimating = true;
$("#flip-container>div").each(function(index){
if($(this).css("display")!=="none"&&index<3){
isAnimating=false;
}
});
if(!isAnimating){
$('#flip-container').quickFlipper({}, flipid, 1);
}
return false;
});
});
[EDIT]
And this is the updated answer jsfiddle demo
Hope this is helpful for you.

There are few solutions that i know can solve your problem.
Have a look at Callback which is used to make another function wait to the other function to finish first before performing, and you can put it together with Unbind function or Event.Prevent
Code may look something like this:
$('document').ready(function () {
$('#flip-container').quickFlip();
$('#flip-navigation li a').each(function () {
$(this).click(function () {
$('#flip-navigation li').each(function () {
$(this).removeClass('selected');
$(this).$('#flip-navigation li a').unbind('click', handler); //Mod 1
});
$(this).parent().addClass('selected');
var flipid = $(this).attr('id').substr(4);
//Mod 2 ---- Start
$('#flip-container').quickFlipper({}, flipid, 1, function(){
$(this).$('#flip-navigation li a').bind('click', handler);
});
//Mod 2 ---- End
return false;
});
});
});
I am not entirely sure how to implement callback on the plugin, but here is a link to you that might be able to give you some idea how to implement callback on the quickflip plugin.

Related

Why Doesn't Modal FadeOut Slowly?

I inherited this modal/overlay/content close/empty method that works, but abruptly:
method.close = function () {
$modal.hide();
$overlay.hide();
$content.empty();
$(window).unbind('resize.modal');
};
To fade out gradually, I modified the method like below, but elements are left behind and subsequent clicks don't open new modals loaded with content, only the overlay:
method.close = function () {
$modal.fadeOut('slow', function() {
$(this).hide();
});
$overlay.fadeOut('slow', function() {
$(this).hide();
});
$content.fadeOut('slow', function() {
$(this).empty();
});
$(window).unbind('resize.modal');
};
What am I missing?
UPDATE: The solution is a single nested callback, based on garryp's answer, like this:
method.close = function() {
$overlay.fadeOut('slow', function() {
$overlay.hide();
$content.empty();
});
$modal.hide();
$(window).unbind('resize.modal');
};
Hide is asynchronous; the calls you have in your original code do not block while the transition occurs, execution moves immediately to the next. You need to use callbacks, like this:
var me = $(this); //Added to ensure correct this context
$modal.fadeOut('slow', function () {
me.hide(function () {
$overlay.fadeOut('slow', function () {
me.hide(function () {
$content.fadeOut('slow', function () {
me.empty();
});
});
});
});
});
Assuming the rest of your code is correct this should ensure the transitions fire one after the next.
Firstly, you do not need $(this).hide(). JQuery fadeOut automatically set display: none at the end of fading animation (read more: http://api.jquery.com/fadeout/).
That mean, in your case $content element will also have display: none after fadeOut animation. I expect you forgot to add $content.show() in modal open method.

Sequential order of Javascript functions

I'm having a bit of a problem with Javascript. I have a list of article titles which, when you click a title, the corresponding article appears on the right hand side (fixed at the top of the page). I have got these articles to fade in/out using Javascript. I also have a function which, when you are scrolled down and click on an article title, scrolls the page slowly back up to the top.
The problem I have is that when the page scrolls up and the article changes at the same time, the animations on both become quite choppy, especially in Safari. Is there any way to make the page scroll to the top first, then make the article change?
I'm basically asking if there is away to make my Javascript functions happen one after the other, rather than at the same time?
Heres my Javascript:
$(document).ready(function () {
$('.scrollup').click(function () {
$("body").animate({
scrollTop: 0
}, 'slow');
return false;
});
$('.articlelist ul li').click(function() {
var i = $(this).index();
$('.fullarticle').fadeTo(500,0);
$('#article' + (i+1)).fadeTo(500,1);
});
});
Any help would be hugely appreciated!
Thank you
I'm guessing you want to keep the click functionality on your article list and only the elements with class scrollup have 2 animations.
$(document).ready(function () {
$('.articlelist ul li').click(function () {
var i = $(this).index();
if ($(this).is(".scrollup")) {
$("body").animate({
scrollTop: 0
}, 'slow', function () {//when animation completes
fadeArticle(i);
});
} else {
fadeArticle(i);
}
});
function fadeArticle(i) {
$('.fullarticle').fadeTo(500, 0);
$('#article' + (i + 1)).fadeTo(500, 1);
}
});
In your call to animate() you'd want to add a function to be called upon completion. The animate function provided by JQuery takes a function as an optional parameter. When the animation completes that function is called.
You could use something like this:
$('.scrollup').click(function () {
$("body").animate({
scrollTop: 0
}, 'slow', showArticle);
return false;
});
showArticle would be a call to a function that fades the article in like the anonymous one in your click listener. You would probably need some way to pass an argument about which article should be shown.
I'm relatively new to this, but I think this may work. What I'm trying to do is enclose each of these as a callable function and then pass one function as the callback to the other.
$(document).ready(function () {
scrollTop(showArticle());
});
function scrollTop(callback) {
$('.scrollup').click(function () {
$("body").animate({
scrollTop: 0
}, 'slow');
callback;
});
}
function showArticle() {
$('.articlelist ul li').click(function () {
var i = $(this).index();
$('.fullarticle').fadeTo(500, 0);
$('#article' + (i + 1)).fadeTo(500, 1);
});
}

Hiding Siblings

$('#navigation li.parent').mouseover(function () {
$('#news-ticker').hide();
$('ul.child', this).slideDown();
});
$('#navigation .child').mouseleave(function () {
setTimeout(function(){
$(this).hide();
$('#news-ticker').slideDown();
},2000);
});
... almost works, just one issue, how do I hide the subnav siblings? If I do $('ul.child', this).slideDown().siblings().hide(); it hides the whole parent.
Try:
$('#navigation li.parent').mouseover(function () {
$('#news-ticker').hide();
$(this).parent().find("ul.child").not($('ul.child', this)).hide();
$('ul.child', this).slideDown();
});
$('#navigation .child').mouseleave(function (e) {
setTimeout(function(){
$(this).hide();
$('#news-ticker').slideDown();
},2000);
e.stopPropagation();
});
Just hide all of your elements before you show the one you want open.
$('ul.child', this).hide();
$('ul.child', this).slideDown();
In the slideDown method I think you can give it two parameter like so:
slideDown(500,function(){$(this).fadeOut(500,function(){$(this).hide();});});
First being interval, second being a callback function. A function called once finished.
But with your code I'd suggest using the hover method:
$('#navigation li.parent').hover(function(){
//on mouse enter
$('#news-ticker').hide();
$('.child', this).slideDown(500);
},function(){
//on mouse leave
$('#new-ticker').slideDown(500,function(){$('.child',this).hide();});
});
Little hard to tell what I'm suppose to be doing without the html. Sorry.

Prevent Double Animation in jQuery

How can I stop this function from happening twice when a user clicks too fast?
$(document).ready(function() {
$(".jTscroller a").click(function(event) {
event.preventDefault();
var target = $(this).attr("href");
$("#photo").fadeTo("fast", 0, function() {
$("#photo").attr("src",target);
$("#photo").load(function() {
$("#photo").fadeTo("fast", 1);
});
});
});
});
The issue I'm having is that if a user clicks too fast the element won't fade back in, it just stays hidden.
The issue wasn't what I thought it was. When I was clicking on the same thumbnail it would try to load in the same image and stick loading forever. The .stop() answer does fix double animation so I'm accepting that answer, but my solution was to check if the last clicked item was the currently displayed item. New script:
$(document).ready(function() {
$(".jTscroller a").click(function(event) {
event.preventDefault();
var last = $("#photo").attr("src");
var target = $(this).attr("href");
if (last != target) {
$("#photo").stop().fadeTo("fast", 0, function() {
$("#photo").attr("src",target);
$("#photo").load(function() {
$("#photo").fadeTo("fast", 1);
});
});
};
});
});
Well you use the correct word in your descripton. Use stop()
$("#photo").stop().fadeTo("fast", 0, function() {
You may use a setTimeout function to make a delay between click grabs. I mean, a second click will be processed only after sometime, after the first click. It sets an interval between clicks.
$(document).ready(function() {
var loaded = true;
$(".jTscroller a").click(function(event) {
if(!loaded) return;
loaded = false;
event.preventDefault();
var target = $(this).attr("href");
$("#photo").fadeTo("fast", 0, function() {
$("#photo").attr("src",target);
$("#photo").load(function() {
$("#photo").fadeTo("fast", 1);
loaded = true;
});
});
});
});
Keep track of its state
I believe what you are looking for is .stop()
http://api.jquery.com/stop/
$("#photo").stop(false, false).fadeTo()
I would prevent it like this:
var photo = $("#photo");
if (0 == photo.queue("fx").length) {
foto.fadeTo();
}
I differs from stop as it will only fire when all animations on this element are done. Also storing the element in a variable will save you some time, because the selector has to grab the element only once.
Use on() and off() :
$(document).ready(function() {
$(".jTscroller a").on('click', changeImage);
function changeImage(e) {
e.preventDefault();
$(e.target).off('click');
$("#photo").fadeOut("fast", function() {
this.src = e.target.href;
this.onload = function() {
$(this).fadeIn("fast");
$(e.target).on('click', changeImage);
});
});
}
});

Help needed Pausing/Resuming FadeIn and FadeOut

Hopefully this is a simple request. I found this code that will work perfectly for what I want to do (Rotate through list items while fading in and out) http://jsfiddle.net/gaby/S5Cjm/1/ . However, I am looking to have the animation pause on mouse over and resume on mouse out. I am a novice at the moment with Javascript and JQuery, so any help would be appreciated.
Thanks.
EDIT: Side questions: Is there a benefit to using JQuery to do this? Would a stand alone script be more appropriate?
I attached the hover event to your list items. The over function stops the animation and all following animations using jQuery.stop(true). The out function resumes the animation:
http://jsfiddle.net/US4Fc/1/
var duration = 1000
function InOut(elem) {
elem.delay(duration).fadeIn(duration).delay(duration).fadeOut(
function() {
if (elem.next().length > 0) {
InOut(elem.next());
}
else {
InOut(elem.siblings(':first'));
}
});
}
$(function() {
$('#content li').hide().hover(
function() {
$(this).stop(true)
},
function() {
var curOp = Number($(this).css("opacity"));
$(this).fadeTo(duration*(1-curOp), 1, function() {
InOut($(this))
});
}
);
InOut($('#content li:first'));
});
Will this work for you?
$(function(){
var active;
$('#content li').hide().hover(
function(){
active = $(this).stop();
},
function(){
active && InOut(active);
}
);
InOut( $('#content li:first') );
});

Categories