Proper use of stop and delay - javascript

I have some issues with my js code. I want to animate a simple click function so that a div, shows the div below but animates back after say 5 seconds. I think I got the right setup with fadeToggle and delay but I just don't get it how to set up "over-clicking" prevention. I mean when people mess with the click-object.
My first attempt was stop(true,true). Although it seems that it works as expected (aborting further function execution) it unfortunately shows the underlying div after 5 seconds although it should show the upper one (picture).
Here is the js and the fiddle:
$(function() {
$("#boxes li").on("click", function(){
$(this).find(".front,.back").stop(true, true).fadeToggle(800).delay(5000).fadeToggle(800);
});
});
but also a js fiddle link to see what I mean:
http://jsfiddle.net/sfiddle/bqbPL/
Regards,
PS: try first to click once to see what effect I want to accomplish and then click 2 times to see how after 5 seconds it will show the text div.

I have modified it a bit,
but still require some work on it, you may use some flag variable with click,
Please see the updated 'fiddle`, it handles the process but stores the next click that occurs after it fade back.
Update: to avoid double clicking
Creating a flag is, you will create a Boolean variable, that will be true/false. (or int variable with 0 or 1),
Like:
var flg=true;
Now, this variable called flag, flag is initiated with False/True value(as per requirement) then we will modify flag after the event occur(the event we want to watch out, here click of button) once event occurs we will change the flag.
In the second you will add flag to condition. if( condition == true && flag == true) {....} so, if flag is changed to false after event/click the event in if will not occur again.
I hope this will help..

Related

How to automatically click() dynamically created elements

I understand that you can bind an event listener to dynamic elements, but I want to have the js automatically click them. As in, there is a webpage with a series of buttons that pop up, I want to automatically click thru them, but each successive button is loaded dynamically and so I cannot do it simply.
Here's what I was hoping would work (works if you type it into console one line at a time):
$(".begin").click().delay(200);
$(".answer[value='1']").click().delay(200);
$(".answer[value='10']").click().delay(200);
If I don't misunderstand your problem. You want to click those buttons "once" they exist. Then you might create a timer after $('.begin')(here I assume the begin is to trig the button appear action) and constantly check those buttons and click them once it's active. It would look something like the following with setTimeInvertal(). And yes you need to create your own condition to stop or determine whether trig click or not.
You have to detect them manually, faster check = once (I assume you are not doing something illegally or abusing websites). The below code is a sample idea.
var btn_timer;
function startAction() {
//for example check every 3s
btn_timer = setTimeout(function(){
//check if btn exists or not
if($(".answer[value='1']").length) {
$(".answer[value='1']").click().delay(200);
}
//condition to stop your timer, or you can manually call it somewhere else;
if(...some condition) StopAction();
}, 3000);
}
function StopAction() {
clearTimeout(btn_timer);
}

Changing the value of jQuery's $(this) object inside an event

I'm wanting to click an image (img#first) and have it split into three smaller versions of another image (img.cat). Each time img.cat is clicked, it throws the cloned elements in random directions and temporarily shows a lion in place of the img.cat that was clicked.
The cat replication and lion popup both work properly (as you can see by clicking the smaller cat in the upper left corner), but I don't know how to make it so a .click() event on img#first will call the function to replicate smaller cats. To reiterate, I want the img#first to spawn 3 smaller img.cat, then disappear, then if the user continues to click new img.cat objects they continue to spawn more of themselves. The problem is just getting that original img#first to start the chain reaction and then disappear forever.
Here's the Fiddle.
If I'm able to just make the entire .click(explode) function work on img#first and then swap that identifier somehow to img.cat after the initial click, wouldn't that do the trick?
For example:
var firstRun = 0
$('img#first').click(function() {
if (!firstRun) {
//do original stuff here
firstRun = 1;
} else {
$(this) = $('img.cat');
//do img.cat stuff here
}
});
Or do I need to isolate the explode function so that it can be called separately on two different objects while achieving the same effect?
I honestly have no idea how to go about accomplishing either of these tasks. Maybe there's a simpler way to get what I want.
Add a separate event which triggers only on clicking #first which programmatically triggers a click on img.cat then removes itself like this:
$('#first').click(function() {
$("img.cat").trigger("click");
$(this).remove();
});
Here is a working jsFiddle.
Update your $('img.cat').click() event listener's selector to $('img.cat, img#first) to select both img.cat and img#first. With this new event listener, you can remove your first $('img#first').click() listener. See my updated JSFiddle.

Why is jQuery .prop not working, seemingly?

Sql Fiddle example
$('#myBox').click(function(e){
e.preventDefault();
e.stopPropagation();
$('#myBox').prop("checked", !$('#myBox').prop("checked") );
});
I'm attaching this to a checkbox so that the check toggling is controlled by my javascript instead of by the default behavior, and it just won't work. I can't figure out why!
My reason for doing this: IE has a double-click filter, so to speak, so that double-clicking checkboxes only registers as a single click. This happens to stop people from toggling checkboxes really fast, which is a feature I need for my application, strangely enough. So I'm just canceling its default functionality and catching clicks by hand with JavaScript/jQuery and toggling it that way, thus eliminating the "speed limit." Except I don't know how to stop the clicks from toggling it in the first place, hence this question.
setTimeout(function() {
$('#myBox').prop("checked", !$('#myBox').prop("checked") );
}, 1);
The delayed timer of 1 millisecond is all it takes.
See this in your jsFiddle, modified.
I'm guessing you want to run something when your checkbox changes...
In that case you should be catching the change event:
$('#myBox').bind('change', function() {
// Do checks here, if you don't want it to change, then deal with it then
});

Sharing an event across two scripts or using change is visibility state as an event trigger

OK I am lost here. I have read numerous postings here and else where on the topic of how to check for the state of a given element in particular whether it is visible or hidden and make the change of state trigger an event. But I cannot make any of the suggested solutions work.
Firstly, as every one seems to leap on this point first, the need to do this has arisen as I have one jQuery script which deals with displaying an svg icon in a clickable state. And another which already has functions to perform relevant actions when the form is made visible by clicking the icon and obviously I want to reuse these.
What I have tried:
Initially I tried have both the scripts acting on a single click event (this remains the ideal solution)....
Script 1:
$(".booked").on("click", function() {
$("#cancellation_Form_Wrapper").css("visibility","visible");
}).svg({loadURL: '../_public/_icons/booked.svg'});
Script 2:
$(".booked").on("click", function() {
// do stuff
});
This did not work so I tried to research sharing an event across two scripts but couldn't make any head way on this subject so I tried triggering another event for the second script to pick up....
Script 1:
$(".booked").on("click", function() {
$("#cancellation_Form_Wrapper").css("visibility","visible");
$("#cancellation_Form_Wrapper").trigger("change");
}).svg({loadURL: '../_public/_icons/booked.svg'});
Script 2
$("#cancellation_Form_Wrapper").on("change", function(event){
// do stuff
});
This did not work again I am unclear why this didn't have the desired effect.
Then I tried is(:visible) ....
Script 1
$(".booked").on("click", function() {
$("#cancellation_Form_Wrapper").css("visibility","visible");
}).svg({loadURL: '../_public/_icons/booked.svg'});
Script 2
$("#cancellation_Form_Wrapper").is(":visible", function(){
// do stuff
});
So I am a bit lost. The ideal would be to return to the first notion. I do not understand why the click event on the svg cannot be handled by both scripts. I assume that this has something to do with event handlers but I am not sure how I could modify the script so they both picked up the same event.
Failing that I could use the fact the visibility state changes to trigger the action.
Any guidance welcomed.
Edit Ok I have just resolved the issue with script 2 picking up the triggered event from script 1. Sad to say this was a basic error on my part ... the form was preventing the display of the alert. However I still cannot get the is(:visible) to work.
Your syntax may be off:
$("#cancellation_Form_Wrapper").is(":visible", function(){
// do stuff
});
should be:
if($("#cancellation_Form_Wrapper").is(":visible")){
// do stuff
});
EDIT: If you want something to happen after a div is made visible, you may want to use the show() callback rather than toggling visibility:
$('#cancellation_Form_Wrapper').show(timeInMilliseconds, function(){
// do something
});
However, this needs to take place in the same function, which I don't think improves your position.
The problem is probably that your second on() script is firing at the same time as your first, meaning the wrapper is not yet visible. You could try wrapping the second on() in a short timeout:
$(".booked").on("click", function() {
setTimeout(function(){
if($("#cancellation_Form_Wrapper").is(":visible")){
// do stuff
});
}, 100);
});
That should introduce enough of a delay to make sure the wrapper has been shown before trying to execute the second statement.

JavaScript/jQuery: global variable inexplicably being reset, causing menu contraction issue

http://jsfiddle.net/VhjR7/1/
When you click the my lists menu once, it expands, but if you click it again, it doesn't contract.
The problem is listsExpanded being inexplicably reset to false after it is set properly to true by listsExpand(). This causes the check within $('#mid-wrap').delegate() to inappropriately call listsExpand() again, instead of listsContract() like it should.
I can't figure out where or why this reset is occurring, but I think it has something to do with the sticky light blue menu functionality. Before I started removing and replacing this blue bar after scrolling to fix an IE7 bug, there was no issue with expansion/contraction of the little white menu.
Any ideas on what's causing this?
The issue is that the hover event does not support both function arguments (in and out) when used with .delegate(). You will need to use mouseenter and mouseleave instead of hover.
Change to this:
$('#mid-wrap').delegate('#lists', 'mouseenter', function() {
listsMouseIn = true;
}).delegate('#lists', 'mouseleave', function() {
listsMouseIn = false;
});
FYI, if these HTML objects are static, not added dynamically, you could significantly simplify your code by using direct event handlers on that actual objects rather than .delegate and just stopPropagation() when you've processed the click. Then, you'd see the click first in the object and wouldn't be processing the same click multiple times causing you to need all these global flags to keep track of state.
You could also just use the visibility of the object as your detection mechanism for whether the menu is open/closed too rather than a global variable.
The first part of your hover handler (with listsMouseIn = true;) never actually fires so whenever you click, your $('body').mouseUp() handler assumes that you are not hovering the lists button, and therefore hides the menu just for the $('#mid-wrap').delegate(...) handler to show it again milliseconds later.
Replacing
$('#mid-wrap').delegate('ul#lists', 'hover', funcIn, funcOut);
with
$('#mid-wrap').delegate('ul#lists', 'mouseover', funcIn).
delegate('ul#lists', 'mouseout', funcOut);
seems to do the trick.

Categories

Resources