How to avoid duplicate each loop in jquery? - javascript

I had a function that looks like this
function show_services_title(show_services){
$('.service').fadeOut();
$.each($('.service'), function(i) {
$(this).delay(500*i).fadeIn();
});
}
Now, this functions is invoked when I click on a link, the problem is that when I click the link the function start to show each div with the class 'service', but when I click the link again and the divs haven't finish showing yet then occur a mess in the screen.
Here is an example that simulate the behavior I'm trying to describe and I want to avoid.
http://jsfiddle.net/bw7jn/4/

Try to disable running the animation the second time when the previous animation is still running.
$(document).ready(function(){
$('#link').click(function(){
show_services_title();
});
});
function show_services_title(show_services){
//if we're already animating, don't start a new one
if($('ul').attr('data-animating') != 'true'){
//make sure other clicks dont trigger this animation
$('ul').attr('data-animating', 'true');
$('.service').fadeOut();
$.each($('.service'), function(i, element) {
setTimeout(function(){
$(element).fadeIn();
//check if this is the last element we're gonna animate
if(i == $('.service').length-1){
//animation is done, allow new animations to start
$('ul').attr('data-animating', 'false');
}
}, 500*i);
});
}
}
http://jsfiddle.net/bw7jn/7/

Related

How to re-enable button hovers in jquery

http://codepen.io/Snowfiring/pen/oKpBh
I'm attempting to disable the animation on click because when clicked, the animation starts moving and if your still hovered over an object it freezes, the end result is the animation stops running and it just moves,
my code to freeze the animation on hover is
function show_box() {
if($(window).width() > 768) {
$('.tab-content').hide(0,
function() {
$(this).prev().css('right', '29.337803855%');
$(this).prev().children().children().click(function () {
$('.favorite').off('mouseenter').css('-webkit-animation-play-state', 'running');
$('.secret').off('mouseenter').css('-webkit-animation-play-state', 'running');
$('.current-projects').off('mouseenter').css('-webkit-animation-play-state', 'running');
$('.tab-selection').animate({right: 0}, 3000).queue(function() {
$('.tab-content').show(1000);
});
$('.favorite').on('mouseenter');
$('.secret').on('mouseenter');
$('.current-projects').on('mouseenter');
});
}
);
}
}
to disable hover on mouseenter and mouseleave i used
.off('mouseenter')
but after the function is done, and the moving complete I set
.on('mouseenter')
but it doesn't re-enable.
At first your code could be much shorter, i think.
And please take a look in the jQuery doc for the on function it does Not, what you are expecting!
I think you should set a global variable if it is disabled at the moment and in the eventhandler you firstly check the variable and abort if its disabled.

While loop condition changed in jQuery

The while loop condition I want to change is done by clicking on a button, while a second button continues the loop and adds to a counter. The problem is the code doesn't wait for jQuery to load and therefore creates an infinite loop. I wasn't able to use setInterval() because the code also includes counters for variables used elsewhere in my code.
var condition = true;
while(condition === true) {
$('#modal').modal();
$('#modalButton1').on('click', function() {
variableCounter++;
});
$('#modalButton2').on('click', function() {
condition = false;
});
}
You are assigning the click event handlers continuously in the while loop. Instead you should define the event handlers once in the document-ready section and then put the desired functionality (i.e. end the modal dialogue when button 2 was clicked) into the handler function for these click events.
$(function(){
$('#modalButton1').on('click', function() { variableCounter++; });
$('#modalButton2').on('click', function() { $('#modal').hide(); })
});
I don't know whether .hide() will achieve what you want. You should call the relevant function for shutting down your modal dialogue here.

Stop & reenable hover with click

I have a container that fades on a timer when hovered on (#module-container) but when clicking on a .return-news, it stops the hover and keeps it from fading. Now I need it where, when called through a function, I need to allow the hover effect again on the #module-container just like before. Here's the hover code:
var module = $('#module-container');
$('.menu-control').add(module).mouseenter(function() {
module.stop().show();
clearTimeout(window.mtimer);
console.log('hovered');
});
$('.menu-control').add(module).mouseleave(function() {
var time = 3000;
window.mtimer = setTimeout(function() {
module.fadeOut(600);
}, time);
console.log(window.mtimer);
});
By clicking .return-news, I've successfully stopping the hover with this line:
$('.return-news').on('click',function(e) {
e.stopPropagation();
module.add('.menu-control').off('mouseenter').off('mouseleave');
console.log('stop it!');
});
NOT WORKING: If I click .next-video then I need to re-enable the hover (which will then use the mouseeneter and mouseleave functions previously declared). I've tried calling this line but it doesn't work:
$('.next-video').on('click',function(e) {
e.stopPropagation();
module.add('.menu-control').on('mouseenter').on('mouseleave');
});
Later, I'll be having the hover re-enabled by calling it using Vimeo's API (instead of the .next-video click) but for the sake of time, I stripped the code to it's basic functionality.
HERE'S THE CODE ON JSFIDDLE.

Dont' allow to click button/icon more than once

I am creating a whack-a-mole style game where a sum is given and numbers animate from the bottom of the container to the top. The aim of the game is to click the correct answer to the sum and collect as many correct answers as possible.
My problem is that the user can click the numbers and other icons multiple times, causing it to crash. Is there a way to overcome this?
I have tried this jQuery one function
$(".character").one("click", function() {
});
But the icons re-appear so I need them to be clickable again.
I have also tried to set a time out but cannot seem to get it working. Can someone point e in the right direction.
setTimeout(function() {
$(".character").one("click", function() {
});
}, 3000);
Fiddle: http://jsfiddle.net/GvNB8/
Your main problem is that you are not interacting with the characters when re-showing them. In that case the only way to prevent the user from clicking is building in a method to prevent clicking twice in quick succession with a timeout.
That method would look something like this:
function clickThrottled(fn) {
var click = true;
return function () {
if(click) {
click = false;
fn.apply(this, arguments);
setTimeout(function () { click = true; }, 1000);
}
};
}
You then use the function like this:
$('.character').click(clickThrottled(function () {
// do your one time magic.
}));
What I am using here is JavaScript closures. The function you pass to the click event handler will only call the underlying function once, then ignore all calls for 1 second and then re-enable itself.
I'd still suggest you go with a normal method of just re-enabling the elements when they are redrawn onto the screen - but the above also works..
Why not just add an information indicating that this item has been clicked :
$(".character").click(function(){
if(!$(this).data("hasBeenClicked")) {
$(this).data("hasBeenClicked", true);
// the rest of your logic ...
}
});

Prevent events to be triggered unecessarily

$('#menu > li').hover(function(){
$(this).find('ul').slideDown();
});
$('#menu > li').mouseleave(function(){
$(this).find('ul').slideUp();
});
this works fine, but if i hover/leave an <li> item of the menu many times and very fast, once i stop i will see it slide up and down as many times as i hovered,
please watch this sort video capture
http://www.screenr.com/dkes
¿how can that be prevent?
You can use stop to stop the current animation. You could also combine your two event handlers and just use hover (which can take 2 arguments, the first is a function to run on mouseenter, the second a function to run on mouseleave):
$('#menu > li').hover(function() {
$(this).find('ul').stop(true, true).slideDown();
}, function() {
$(this).find('ul').stop(true, true).slideUp();
});
The first argument is clearQueue, which will stop the animations queueing up endlessly as you hover repeatedly. The second argument is jumpToEnd, which forces any currently running animation to end before starting a new one.
Here's a simple example.
It all boils down to you having a variable that will store the state of your sliding and will prevent further requests from happening if a sliding is already taking place.
Set the flag at the beginning of sliding and use callback to unset the flag.
var closing = false;
$('#menu > li').mouseleave(function(){
closing = true;
$(this).find('ul').slideUp(null, function(){
closing = false;
});
});
// then in the hover method you would just check the value of closing to see if to allow or not opening.
The second idea was exposed a little earlier by James Allardice, and I like it more if it works.

Categories

Resources