jquery delay doesn't count as animation - javascript

I'm trying to do an animation after button click using promises. But no matter what I do, it will still let me keep clicking.
I'm showing some Bootstrap form validator classes and then removing them. Like this:
messageEffect : function(container) {
return container.fadeIn(100).delay(1000).fadeOut();
},
$.when(this.messageEffect($container)).done(function() {
$container.empty();
$icon.remove();
$group.removeClass('has-feedback has-' + alertType);
});
I'm calling this function called "showAlert()" after some stuff, if something fails, I show the error message below the input field.
Thing is, if I keep clicking and clicking, it will spam the message spans, until they disappear (of course) due to the animation.
I tried using the ('div-that-is-animating').is(':animated') but didn't work, I can still spam them.
I also tried doing an unbind of toggle and click before calling this "showAlert()" function, but didn't work either.
Is it because delay(1000) there isn't counting like an animation? Or what else I can try?
Thanks in advance.

See if this works (assuming your button id is myButton):
messageEffect : function(container) {
$('#myButton').attr('disabled', true);
return container.fadeIn(100).delay(1000).fadeOut();
},
$.when(this.messageEffect($container)).done(function() {
$('#myButton').attr('disabled', false);
$container.empty();
$icon.remove();
$group.removeClass('has-feedback has-' + alertType);
});

Related

Jquery bug dblclick/click

I've been experimenting with jquery and have come upon a problem. http://javascript.nicklewers.co.uk/nav/
On the 'Android' tab I've set it so that if you click once, the sub menu will appear, however when doubleclicking, the main content will appear.
Now the problem is: a double click involves two single clicks which involves the sub menu opening and closing very quickly and this looks bad. How do I prevent this?
try this (using a timer to know if single click or double):
alreadyclicked=false;
$('#android').bind('click',function(){
var el=$(this);
if (alreadyclicked)
{
alreadyclicked=false; // reset
clearTimeout(alreadyclickedTimeout); // prevent this from happening
// do what needs to happen on double click.
}
else
{
alreadyclicked=true;
alreadyclickedTimeout=setTimeout(function(){
alreadyclicked=false; // reset when it happens
// do what needs to happen on single click.
// use el instead of $(this) because $(this) is
// no longer the element
},300); // <-- dblclick tolerance here
}
return false;
});
Try a delay before showing/hiding the submenu. With JS this can be done using the setTimeout() function.
$('#android').dblclick(function(){
$('.content, #subnav').toggle();
});
why do you toggle both the content and the submenu? Removing it is not going to solve the problem, but I think it should not be there.

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 ...
}
});

Sequence of Events, alert is faster then removeAttr

i got following problem, i need to build a two checkboxes; where only one can be selected at a time, but onchange there will be a live calculation.
$('#calculator input, #calculator select').change(function() {
$('#calc_keller_true').click(function() {
$('#calc_keller_false').removeAttr('checked');
});
$('#calc_keller_false').click(function() {
$('#calc_keller_true').removeAttr('checked');
});
liveCalculate();
});
This is how it looks like, which is working but it seems to slow cause in my function liveCalculate i do this.
function liveCalculate() {
// Getting the value of the checked checkbox
var calc_keller = $('input[name=calc_keller]:checked').val();
alert(calc_keller);
}
So when i click on the false button the alert will trigger before my removeAttr and both Checkboxes will be 'checked' at the moment of the alert.
Anyone got a plan why exactly the liveCalculate function triggers faster then the removeAttr ?
Do i miss some basic knowledge in how the order works in javascript ?
Best Regards,
jay7
You only need to add click-handlers once. In your above example, you are adding them again and again, for every 'change' event you have on the select box.
Furthermore, you are not actually removing the attr on the change event, that happens during the click events. However, you fire liveCalculate after the change event.
Consider the following:
$('#calc_keller_true').click(function() {
$('#calc_keller_false').removeAttr('checked');
});
$('#calc_keller_false').click(function() {
$('#calc_keller_true').removeAttr('checked');
});
$('#calculator input, #calculator select').change(function() {
$('#calc_keller_false').removeAttr('checked');
$('#calc_keller_true').removeAttr('checked');
liveCalculate();
});
I'm not entirely sure if that accomplishes what you're expecting (simply because it isn't 100% clear to me what you do expect to happen).

check for ('div')mouseenter on ('a')mouseleave

my problem is following:
I got a trigger(a) and a popup(div). The div doesn't lie nested inside the anchor.
When I hover over a, I want the div to show up.
When I go from a to the div, I want it to stay visible.
When I leave the div, I want it to close.
When I hover over a and leave without entering the div, I want the div to close.
I got most of that figured out, but now I'm struggeling with requierement no. 2.
When checking for mouseleave on a, I check if there is a mouseenter on the div. If it is, I want to abort the mouseleave. If not, I want to close the div.
What am I doing wrong? Is this even the right way to do this?
Here's the markup:
<a href="#" class="popup_toggle" style='display:block;width:50px;height:50px;border:1px solid red;position:relative;'>Toggle</a>
<div class="popup_div" style='position:absolute;top:50px;left:0px;border:1px solid blue;display:none;'>Popup</div>
Here's the jQuery:
$('.popup_toggle').mouseenter(function() {
var element = $(this).next('.popup_div');
$.data(this, 'timer', setTimeout(function() {
element.show(100);
}, 500));
});
$('.popup_toggle').mouseleave(function() {
clearTimeout($.data(this, 'timer'));
if($('.popup_div').mouseenter==true)
{
return false;
}
else
{
$('.popup_div').hide(100)
};
});
What you're trying to do is fairly simple. When entering the trigger, identify the panel (layer, popup, whatever), save reference to each other using .data() and have the event handlers check if the related targets are either the trigger (from the panel view) or the panel (from the trigger view). I threw something together. Have a look at the console log to see how this works… http://jsfiddle.net/rodneyrehm/X5uRD/
That will most likely not work...no. I would suggest that you add a mouseenter and mouseleave callback to you <div> element as well and have them set a global variable that tells your other callbacks how to handle their events, i.e. "if global variable is true, don't hide the popup on mouseleave, otherwise hide popup" or something like this.
The other approach would be to check whether the mouse is inside the popup when the mouseleave callback tries to hide the popup. That might be much more work than it is worth though.
I believe the problem with your implementation is that the mouseenter on the div will fire shortly after the mouseleave from the a.
This would give you something like:
$('.popup_toggle').mouseenter(function() {
// Clear any pending "hide" timer
// Set a show timer
});
$('.popup_toggle').mouseleave(function() {
// Clear any pending "show" timer
// Set a hide timer
});
$('.popup_div').mouseenter(function() {
// Clear any pending "hide" timer
});
Note that you'll have to make sure that you access the same timer from both the .popup_toggle event and the .popup_div event. You may want to consider using Ben Alman's doTimeout plugin to help with this. It (usually) results in much clearer code than manually working with setTimeout/clearTimeout.

jquery buffer/queue for effects? Or to tell if an effect is in process?

I have a click event that checks to see if a form is correct i.e. filled out details.. and then i call a function that does this
$('#message_text').html(text);
$('#message_system').fadeIn("slow");
$('#message_system').animate({ opacity: 1.0 }, 5000)
.fadeOut('slow', function() {
$(this).hide();
});
All works ok, as long as i wait .. if i double click the button twice for example that it stops displaying ...
I presume if it is hidden hide() then fadeIn() will automatically show it?
Anyone got any experience with this ??
What i probably would like to do is on the second click then disgard current effects and redisplay new messaage
THanks
I'm not sure if this is what you're after, but have you looked at the stop() method.
You can skip straight to the end of any current animations by calling $('#message_system').stop(true, true) before beginning again.
if ( ! $(this).is(':animated') ) {
// Do the animation...
}

Categories

Resources