jQuery trigger event with delay - javascript

I have a situation in which I have a series of buttons on a page. Clicking a button triggers several functions and runs a series of complex calculations.
Then I have what is essentially a "click all" button that will trigger a click event on each button:
$('.myBtn').trigger('click'); // $('.myBtn') returns a list of all buttons
This works fine in most modern browsers, but in IE the trigger('click') takes a long time to run and I often get a 'script is taking too long' error.
Unfortunately, the way things are set up there's no real way to avoid the heavy calculations on click.
So I'm thinking of adding some sort of delay. So on "click all", trigger btn1 click, wait 200ms, trigger btn2 click, wait... etc.
I've tried things like:
$('.btnAll').each(function() {
var el = $(this);
setTimeout(function () {
el.trigger('click');
}, 200);
});
But I don't think this works correctly because of the way .each() calls are queued or something(?). Event queueing and synchronous calls are still a little unclear to me.
Any thoughts on how I can make this work?

.each() calls are not 'queued', they just execute the given function on each element of the collection, one after the other. So you set for each button-click a timeout of 200ms. The result: 200ms later all buttons are triggered at (nearly) same time. If you want to stagger the clicks with delay in between, you must give them different times like so:
$('.btnAll').each(function(i) { // i is index of this in the collection
var el = $(this);
setTimeout(function () {
el.trigger('click');
}, i * 200); // each button gets a multiple of 200ms, depending on its index
});
This triggers the first button immediately, the second 200 ms later, the third.... .

Try it
function myEach(){
$('.btnAll').each(function() {
$(this).trigger('click');
});
}
setTimeout(myEach(),200);

Related

How can I pause my infinitely looping animating divs on click using Jquery/javascript?

Hi I have 4 windows 8 style live tiles on my web page each of them are infinitely looping to animate sliding up and down. I can get this to work well using a method that calls itself. However I want to pause this animation once the user clicks on one of the tiles. Once a tile is clicked it expands to the full size of the page but the animation continues when I want it to stop. I have tried implementing the stop() function to no avail. I have tried stop(true, true); to no avail. I have tried putting in a "sleep" method that puts the animation delay rate very high(to a stop) and thus putting the animation "to sleep" but it is unreliable getting it to stop on the right slide for some reason. If the stop method does work it only briefly works and the tiles all become out of sync and break I have also tried a boolean check i.e. if clicked stop but still no luck. Does anyone have any suggestions? thanks.
Here is some sample code:
function tiles()
{
setTimeout(function(){alltiles(news1,news2);},4000);
this method gets called on startup and the tile starts animating via alltiles(); after 4 seconds.
This is where the animation gets done I have included a callback function so each animation
starts when the last one has completed. Then the alltiles(); method gets called again to infinitely loop the animation.
function alltiles(div1, div2){
$(div1).delay(delayRate).animate({top: "-100%"}, speed, easing,
function(){});
$(div2).delay(delayRate).animate({top: "0"}, speed, easing,
function(){});
$(div1).delay(delayRate).animate({top: "0"}, speed, easing,
function(){});
$(div2).delay(delayRate).animate({top: "100%"},speed,easing,function(){
alltiles(div1, div2);});
Finally just a sample of where I am implementing the mouse down. I have tried unique ids also with no luck.
$('.tile,.tile2, .tile3, .tile4').mousedown(function(event) {
$('.tile,.tile2, .tile3, .tile4').stop();
$(this).addClass('selected');
$(".tile, .tile2, .tile3, .tile4").not(this).fadeOut(100);
$(this).delay(2000).animate({ width: "98%",height: "98%" }, 1000 );
If you're starting the whole thing with this:
alltiles(news1,news2);
which then proceeds to do animation operations on news1 and news2, then, you need to stop it with this:
$(news1).stop(true);
$(news2).stop(true);
Passing the true argument with .stop(true) clears the animation queue for that particular object so any queued up operations are stopped too.
To put it in your click handler:
$('.tile, .tile2, .tile3, .tile4').mousedown(function(event) {
$(news1).stop(true);
$(news2).stop(true);
$(this).addClass('selected');
$(".tile, .tile2, .tile3, .tile4").not(this).fadeOut(100);
$(this).delay(2000).animate({width: "98%", height: "98%"}, 1000 );
});
Say if you have a button with id="theStopButton". If a user clicks on it, it will stop ALL animations on the page with $.fx.off = true.
$('#theStopButton').click(function() {
$.fx.off = true;
});
http://api.jquery.com/jquery.fx.off/
Try adding the necessary boolean values
http://api.jquery.com/stop/
.stop( true, true )
OR
.stop(true)

why setInterval() cycle goes faster every time?

I'm building a custom slider on Javascript , and I want that every time the user clicks on a div of the slider, the slider should stop for X seconds.
My code is:
$(document).ready(function () {
var ciclo;
var index_slide = 1;
function startSlidercicle() {
ciclo = setInterval( function() {
// Slider code goes here
}, 3000);
}
//Here I start the slider animation
startSlidercicle();
//When the user clicks on a div called 'slide', stop the cycle and start again the animation cycle
$('.slide').on('click', function() {
clearInterval(ciclo);
setTimeout(startSlidercicle(), 3000);
});
});
But the problem is that everytime I click and stop the slider, the cycle starts faster and faster. How can I fix it?
Instead of:
clearInterval(ciclo);
setTimeout(startSlidercicle(), 3000);
or:
clearInterval(ciclo);
setTimeout(startSlidercicle, 3000);
I changed the code to be:
clearInterval(ciclo);
startSlidercicle();
And now the slider just works fine. I think that, in the first two proposals, every time I click on the div, a new function is created, "overlapping" over the existing cycle and, thus, it looks like the slider speeds up, but its just one cycle starting over another.
You need to change this:
clearInterval(ciclo);
setTimeout(startSlidercicle(), 3000);
to this:
clearInterval(ciclo);
setTimeout(startSlidercicle, 3000);
In your existing code, you are calling startSlidercirle immediately and it is not waiting until the setTimeout() fires because you have the () after the function name. That means to execute it immediately and pass the result of executing that to setTimeout(). You want to just pass the function reference to setTimeout() which is done by just having the name of the function with no () after it. This is a common mistake.

Stop duplicate mouse over detection

I have a popup that is executed on mouseover with jquery.
Within that function I have a second delay before the popup displays using settimeout
Problem is if in that second they mouse over multiple times then multiple popups are triggered.
$('#div').mouseover(function() {setTimeout("popup()",1000);});
What I need to do is disable the detection and then re enable it in popup().
How might I do that?
You can use .hover() with a clearTimeout(), like this:
$('#div').hover(function() {
$.data(this, 'timer', setTimeout(popup, 1000));
}, function() {
clearTimeout($.data(this, 'timer'));
});
This clears the timeout you're setting if the mouse leaves, you'll have to stay on the element for a full second for the popup to trigger. We're just using $.data() on the element to store the timer ID (so we know what to clear). The other change is to not pass a string to setTimeout() but rather a reference directly to the function.
I guess something like this
(function(){
var popup_timer = 0;
$('#div').mouseover(function() {
clearTimeout(popup_timer);
popup_timer = setTimeout("popup()",1000);
});
});
EDIT updated code, clearTimeout added, wrapped

jQuery delay doesn't work as expected

I have the following jQuery code
$("#dropdown").hover(function() {
$(this).stop(true,true).fadeTo('fast',1);
$("#options").stop(true,true).slideDown();
}, function() {
$(this).delay(1000).stop(true,true).fadeTo('fast',0.1);
$("#options").delay(1000).stop(true,true).slideUp();
}
);
What I expect to happen is when the mouse leaves #dropdown it will wait 1 second before continuing. This is not happening.
What I am trying to achieve, in case there is a better way, is to leave the drop down menu visible for a second or two after moving your mouse and I would also like to prevent the events from happening again to prevent artifacts and "funnies" if you were to move the mouse over and out from the div very quickly
The problem is .stop(). If you take that out it works:
http://jsfiddle.net/LZ8yt/
Your calls to stop aren't placed on the animation queue - they run immediately. I'm not sure whether you really need them in the "hover out" routine.
edit removed dumbness
You can always go lo-tech with setTimeout.
var dropDownElement = $(this);
setTimeout(function()
{
dropDownElement.fadeTo('fast', 0.1);
// Other Code
}, 1000);

Queuing and stop propagating a click event to inside a div in Javascript

I'm trying to implement a "wait for 3 seconds to do this operation" <div>.
So, I have a <div> that has a bunch of elements in it that I want to be unclickable for say 3 seconds (a timer, or some other event), but somehow capture the events in a queue, and then fire them after the period (or some event of my choice) has elapsed/performed?
I'm thinking this is a problem kind of like putting up a modal dialog, and then not having anything beneath it clickable. Am I right in thinking this?
One possibility is to have the click handler for your DIV respond to clicks on its child elements as the event bubbles up. That handler would perform the queuing until the delay elapsed. Here's a rough example (using jQuery event handling for convenience):
(function() {
var isReady = false, queue = [];
setTimeout(function() {
isReady = true;
processQueue()
}, 3000);
$("#mainDiv").click(function(ev) {
if (isReady) {
//code to handle the click based on which child was clicked (ev.srcElement)
} else {
queue.push(ev.srcElement);
}
});
function processQueue() {
var i, elem;
for (i = 0; elem = queue[i]; i++) {
$(elem).click(); //re-trigger the click event
}
queue.length = 0;
}
})();
Give the div an onclick function, which starts off for the first 3 seconds as just holding an array of calls with their events...then after your 3000 millisecond timer is done, run a function that changes the div's onclick, allows things to be edited, and runs the array of events.
Another thing that Ive found to be helpful is the function.
setTimeout("alert('hello')",1250);
So something along the lines of surrounding all of the elements onclick method with a second method that will store that call for as long as you need.
<div onclick=registerClick("normallyDoThis()")></div>
Then you can setup a timer at the beggining of the time to change the Div and execute all the commands. Possibly with the eval command?
setTimeout("changeTheDiv()", 3000);
function changeTheDiv()
{
/*eval() all the items in a list of onclicks youve been storing up */
/*Then go through and parse out the register() from all the onclick methods*/
}
I hope this helps

Categories

Resources