run animation only if not already running jQuery UI - javascript

I am using jQuery UI's Bounce Effect on a click event like this
$("#myelm").click(function(){
$(".wlbutton").children("span.new").effect( "bounce", "slow");
});
I would want to run the effect only if it's not already running. So if you click twice fast it will only act on the first click. How can I achieve this?
I've tried to clear the queue with jQuery's .stop() without any luck.

You can use .not to filter it:
$('#myelm').click(function(){
$('.wlbutton').children('span.new').not(':animated').effect('bounce', 'slow');
});
However I would use .is function to check instead of a filter because of code readability

Use the :animated selector to check whether the particular element is animating or not. If it is currently getting animated, Just let that click event ignored.
Try,
$("#myelm").click(function(){
var xEle = $(".wlbutton").children("span.new");
if(xEle.is(':animated')) { return; }
xEle.effect( "bounce", "slow");
});
The another way would be using .stop().
$("#myelm").click(function(){
$(".wlbutton").children("span.new").stop().effect( "bounce", "slow");
});
DEMO

Related

.delay() a .css() action by multiplying an index number

I am trying to create a script that does the following:
Waits until a point on the page is reached by scrolling (.clients with an offset of 500px
Start fading in img's contained inside the .clients div once this event is triggered
Fade in with a slight delay between each item (so they fade in in sequence)
Due to other parts of my code the fade-in has to be with change of opacity:1 and cannot be .fadeIn()
I'm somewhere there but having a few issues. Here is my code:
var targetOffset = $(".clients").offset().top;
var $w = $(window).scroll(function(){
if ( $w.scrollTop() > targetOffset-500 ) {
$('.home .clients img').each(function(index){
console.log(index);
$(this).delay(500 * index).css('opacity','1');
});
}
});
First problem
The event does fire at the correct scroll-point in the page, but it continues to fire. I would like it to only fire once and then not register again. When 500 above .clients is reached, the event should fire, and never again.
Second problem
My .each() does not seem to work correctly. Everything fades in at once. My method for making a small .delay() between the fade-ins doesn't seem to be working. I tried multiplying the index by 500. So the first index is 0, so it fires immediately. The second index is 1 so it should fire after 500 milliseconds and so on. I'd like to work out why this method isn't working.
Any help appreciated. I'd appreciate trying to make the code above work rather than writing something entirely new, unless that's the only way. I'd appreciate explanation of what I was doing wrong so I can learn, instead of just pure-code answers.
JSFiddle
Sidney has attacked most of the problems except one. The scroll event fires multiple times, so it checks the conditional multiple times and then actually sets the animation multiple times. To keep this from happening, I typically like to add another boolean to check if the process has fired at all. I've simplified the code to make the changes more legible.
var working = false;
$(window).on('scroll', function(){
if($(window).scrollTop() > 1000 && !working){
working = true;
setTimeout(function(){
working = false;
}, 500);
};
});
As Tushar mentioned in the comments below your post, instead of using .delay() you could use a plain setTimeout().
On the jQuery docs for .delay() they mention that using setTimeout is actually better in some use-cases too - this is one of them.
The .delay() method is best for delaying between queued jQuery
effects. Because it is limited—it doesn't, for example, offer a way to
cancel the delay—.delay() is not a replacement for JavaScript's native
setTimeout function, which may be more appropriate for certain use
cases.
Using setTimeout your code would look like this:
var targetOffset = $(".clients").offset().top;
var $w = $(window).scroll(function() {
if ($w.scrollTop() > targetOffset - 500) {
$('.home .clients img').each(function(index) {
setTimeout(function() {
$(this).css('opacity','1');
}, (500 * index));
});
}
});
Also, you can unbind an event using .off()
so in your if ($w.scrollTop() > targetOffset - 500) { ... }
you could add a line that looks like this:
$(window).off('scroll');
Which would unbind the scroll handler from the window object.
You could also use .on() to reattach it again some time later. (with on() you can bind multiple events in one go, allowing you to write the same code for multiple handlers once.)
Please change your jquery code with following it will trigger event one time only and may be as per your reuirements :-
var targetOffset = $(".clients").offset().top;
var $w = $(window).scroll(function () {
if ($w.scrollTop() == 1300) {
console.log('here!');
$('.clients img').each(function (index) {
$(this).delay(5000 * index).css('opacity', '1');
});
}
});
Here i have take scroll hight to 1300 to show your opacity effect you can take it dynamically, if you want it 500 then please change the css as following also.
.scroll {
height:700px;
}

How to detect when all animations have stopped?

I'm using this code to stop simultaneous animations on 2 elements:
$('#container').find('*').stop(true, true);
The animation can be stopped by an end user hovering over a button, in which case the animation stops after completion (which is what I want). However, the button hover also initiates another function (removes and reloads the elements), and there's a conflict if that function runs before the animations are complete.
I was thinking that using 'after' or 'complete' with the above code might work, but I can't figure out what the syntax would be.
im not sure what you are trying to achieve, but in order to check whether or not there are running/pending animations on the object using jQuery, you can use .promise().done()
example, somehing of this sort:
var animations_running;
$('#container').promise().done(function() {
animations_running=false;
});
$('#container').on("mouseover",".SomethingInside",function(){
if(animations_running==false){
//...do animations...
animations_running=true;
}
});
you can also add a callback function to your jQuery animations as follows:
$('#container').on("mouseover",".SomethingInside",function(){
if(animations_running==false){
$(this).animate({
left:+=50
},500,function(){
//...this is the callback function...
});
animations_running=true;
}
});

How to undo .click(false)

I have a page transition which uses jQuery animate. I found that the following code:
$("body").click(false);
is the best way to stop any mouse clicks on the page while the animation is running. But I'm not sure how to undo it! Any ideas?
Try using .unbind()
$("body").unbind("click");
You can check for :animated length on body click.try this:
$('body').click(function () {
if ($(':animated').length) {
return false;
}
});
show me the animation code snippet. You should place $("body").unbind("click"); in the callback of the animation function. When it's done animating, it will unbind the click again.

jQuery resizable .Live()

When I try to destroy resizable div, hover function on .ui-resizable-se doesn't work. I think I have to use jquery live(). But I couldn't integrate it clearly.
If you hover .ui-resizable-se or .ui-resizable-e when page load, functions will work, but if you hover again, nothing will be happened. How can I overcome this problem?
$('#resizable').resizable({
aspectRatio:false
});
$('.ui-resizable-se').hover(function(){
keep("resizable");
});
$('.ui-resizable-e').hover(function(){
dontKeep("resizable");
});
Source link: http://jsfiddle.net/nNrgP/
The hovers do not work after the first time because you've called resizable("destroy"); Calling that
Removes the resizable functionality completely. This will return the element back to its pre-init state.
Resizable Destroy
If you want that to still be available, you should either toggle between resizable("disable") and resizable("enable"), or completely re-init the resizable div. Without more knowledge of your goal (or other code), it's tough to tell what the best option is.
You could also just update the options:
function dontKeep(val){
$("#"+val).resizable("option", 'aspectRatio', false);
alert("dont keep");
}
function keep(val){
$("#"+val).resizable("option", 'aspectRatio', true);
alert("keep");
}
Try using event delegation since you might be dealing with dynamic eleemnts
$(document).on('mouseenter mouseleave', '.ui-resizable-e', function(){
dontKeep("resizable");
});
$(document).on('mouseenter mouseleave', '.ui-resizable-se', function(){
keep("resizable");
});
Demo: Fiddle

fadeToggle next element in on hover

I have the following code to show the next element in the dom on click, I would like to convert this same code into something I could use for a simple hover event. Does jQuery have a simple method to do something like this or should I be using .bind() to mouseover and mouseout events? I know this should be simple, I am probably just not thinking clearly.
$('#el').click(function(e){
e.preventDefault();
var $prevEl = $(this).parent().find('.prev-el');
$prevEl.fadeToggle();
});
One thing to mention is I would like the $prevEl to stay visible after hovering the triggering #el element. What is the best way to go about this?
Thank you in advance,
DT
You can use $('#el').mouseover(... instead of $('#el').click(..., but you should use fadeIn instead of fadeToggle when you're using mouseover:
$('#el').mouseover(function(e) {
var $prevEl = $(this).parent().find('.prev-el');
$prevEl.fadeIn();
});
http://jsfiddle.net/mblase75/eXjTb/3/
If you want it to fade back out on mouseout, though, use .hover as a shorthand way to combine the two and keep the fadeToggle:
$('#el').hover(function(e) {
var $prevEl = $(this).parent().find('.prev-el');
$prevEl.fadeToggle();
});
http://jsfiddle.net/mblase75/eXjTb/2/
this should work:
$('#el').mouseover(function(){
$(this).parent().find('.prev-el').fadeIn();
});
By the way, you can use .next() and .prev() instead of .parent().find(...) (depending on your html)

Categories