Why doesn't it fire the alert?
var $anchor = $(this);
$('.hide').val($(this).attr('href'));
$('html, body').animate({
scrollLeft: $($anchor.attr('href')).offset().left
}, {
queue: false,
duration: 1000,
easing: 'easeInOutCirc'
}, function () {
alert('test');
});
There are multiple different syntax options you can use with .animate(). When you pass a properties object and an options object (like you are doing), the completion function goes in the options object not as the third parameter like this:
var $anchor = $(this);
$('.hide').val($(this).attr('href'));
$('html, body').animate({
scrollLeft: $($anchor.attr('href')).offset().left
}, {
queue: false,
duration: 1000,
easing: 'easeInOutCirc',
complete: function () {
alert('test');
}
}
);
This is described in full in the jQuery .animate() doc.
.animate( properties, options )
properties - A map of CSS properties that the animation will move toward.
options - A map of additional options to pass to the method. Supported keys:
duration: A string or number determining how long the animation will run.
easing: A string indicating which easing function to use for the transition.
complete: A function to call once the animation is complete.
step: A function to be called after each step of the animation.
queue: A Boolean indicating whether to place the animation in the effects queue. If false, the animation will begin immediately. As of jQuery 1.7, the queue option can also accept a string, in which case the animation is added to the queue represented by that string.
specialEasing: A map of one or more of the CSS properties defined by the properties argument and their corresponding easing functions (added 1.4).
try to specify the third parameter as "complete" like so:
var $anchor = $(this);
$('.hide').val($(this).attr('href'));
$('html, body').animate({
scrollLeft: $($anchor.attr('href')).offset().left
}, {
queue: false,
duration: 1000,
easing: 'easeInOutCirc'
}, complete: function () {
alert('test');
});
Related
I was working on making my animations work dynamically for various elements when I ran into this problem (right when I was about to finish too). I can't animate properties using the JQuery css() method. I was able to get the animation working with hard coded values for the height, width, and top properties. Here's the snippet:
function shrinkSection(section){
var elem = section.SectionID;
$(elem).find(".content").fadeOut(500);
$(elem)
.animate({top: $(elem).css('top'), height: $(elem).css('height')}, 500)
.animate({width: $(elem).css('width')}, {duration: 500,
complete: function() {
$(elem).find(".icon").fadeIn(500);
$(elem).addClass("active");
}
});
}
console.log() reveals that $(elem).css('[PROPERTY]') IS returning the correct css value. Any ideas why this won't work?
The animate() method queues the effects and waits till the first effect animation is finished to start the second one, so they are serially applied. From jquery docs:
queue (default: true)
Type: Boolean or String
A Boolean indicating whether to place the animation in the effects queue. If false, the animation will begin immediately. As of jQuery 1.7, the queue option can also accept a string, in which case the animation is added to the queue represented by that string. When a custom queue name is used the animation does not automatically start; you must call .dequeue("queuename") to start it.
If you want the animations to happen in "parallel", you can do:
$(elem).find(".content").fadeOut(500);
if( $(elem).length )
$(elem)
.animate( { top: $(elem).css('top'), height: $(elem).css('height')},
{ duration: 500,
queue: false,
complete: function() { alert('callback!!'); } }
)
.animate( { width: $(elem).css('width')},
{ duration: 500,
queue: false,
complete: function() {
$(elem).find(".icon").fadeIn(500);
$(elem).addClass("active");
}
});
else
alert("No elem found!!");
Notice in the example, that you could check that the element elem on which you apply the effect is actually found by jquery.
This way you track possible DOM selector problems also.
I used the following javascript:
$('.slide-content #show-effect-1').hover(function(){
$(this).next().stop(true, true).fadeIn({ duration: _duration, queue: false }).css('display', 'none').show('slide', { direction: "down" }, _duration);
},
function() {
$(this).next().stop(true, true).fadeOut({ duration: _duration, queue: false }).hide('slide', { direction: "down" }, _duration);
});
What should happen is:
mouseenter the button --> content show
mouseout the button --> content hide
Question: when mouseout on the button is faster than the effect time of mouseenter, the content will be hidden and not displayed when mousenter the button again.
How do I prevent this happening?
Instead of using separate funcitons for the fadeIn and slide effect I decided to implement both in a single animate() function, then I just added some CSS resets to make sure the element is ready before starting the animation:
$(document).ready(function () {
var _duration = 1000;
$('#show-effect-1').hover(function () {
var $next = $('.text-banner');
$next.show();
$next.stop(true, true).css({
'margin-left': $next.outerWidth() * -1,
'margin-top': 0,
'opacity': 0,
'display': 'block'
}).animate({
'margin-left': 0,
'opacity': 1
}, _duration);
}, function () {
var $next = $('.text-banner');
$next.stop(true, true).animate({
'margin-top': $next.height() * -1,
'opacity': 0
}, _duration, function () {
$(this).hide();
});
});
});
Check the Updated fiddle
Note that I had to add a container to accurately reproduce the slide effect, you can test without it and see if it's something you actually need
I am trying to animate a number so that it rolls into the number when the page loads. I am using another library to display a dial (http://anthonyterrien.com/knob/). The issue I am having is that the number seems to be different every time I run it. It should be a consistent number ending on 19420. However sometimes it is lower and there doesn't seem to be any particular pattern.
My JS code looks like this:
$(function() {
$('#dial').knob({
min: '0',
max: '25000',
readOnly: true
});
$({
value: 0
}).animate({
value: 19420
}, {
duration: 950,
easing: 'swing',
step: function() {
$('#dial').val(Math.round(this.value)).trigger('change');
}
});
});
The fiddle can be found here: http://jsfiddle.net/ND5Sf/
What have I done wrong or is there anything I've missed out? If not, are these 2 libraries not compatible?
The issue is because you are using step function instead of progress.
Step:
A function to be called for each animated property of each animated
element. This function provides an opportunity to modify the Tween
object to change the value of the property before it is set.
Progress:
A function to be called after each step of the animation, only once
per animated element regardless of the number of animated properties.
(version added: 1.8)
Code:
$(function () {
$('#dial').knob({
min: '0',
max: '25000',
readOnly: true
});
$({
value: 0
}).animate({
value: 19420
}, {
duration: 950,
easing: 'swing',
progress: function () {
$('#dial').val(Math.round(this.value)).trigger('change');
}
});
});
Docs: http://api.jquery.com/animate/
Demo: http://jsfiddle.net/IrvinDominin/JW2gP/
I'm trying in different ways to create a small scrolling method which can take an optional effect callback function. Imagine I can run scrollToEl(el, flash) which would first scroll down to the element and the flash it. How would I normally go about this?
This is what I've done..but it's not really working.
scrollToEl : function(el, callback) {
// flash the selected product
var self = this;
$('html, body').animate({
scrollTop: el.offset().top - 50
}, 1000, 'swing', callback); // how to pass el here as well paired with callback?
}
flash : function(el) {
// flash the selected product
el.animate({
opacity : 0.4
}, 100, 'swing', function() {
el.animate({
opacity : 1
}, 1000, 'swing');
});
},
I want to use it like this:
var el = $('#element');
scrollToEl(el, flash); // how to pass in to the callback function flash?
You can use a closure:
scrollToEl : function(el, callback) {
// flash the selected product
var self = this;
// Get completion callback if any
var completion;
if (callback) {
completion = function() {
callback(el); // See below if you prefer `el` to be `this` in the callback
};
}
else {
completion = $.noop;
}
$('html, body').animate({
scrollTop: el.offset().top - 50
}, 1000, 'swing', completion);
}
More about closures: Closures are not complicated
If you want the callback to receive the element as this, you can use jQuery.proxy instead of your own wrapper function:
scrollToEl : function(el, callback) {
// flash the selected product
var self = this;
$('html, body').animate({
scrollTop: el.offset().top - 50
}, 1000, 'swing', callback ? $.proxy(callback, el) : $.noop);
}
It comes to the same thing, because proxy creates a function. But it doesn't introduce a closure over the context of the call to scrollToEl.
It would be more normal for a callback to have the affected element as this rather than as a parameter:
flash : function() {
// flash the selected product
$(this).animate({
opacity : 0.4
}, 100, 'swing', function() {
$(this).animate({
opacity : 1
}, 1000, 'swing');
});
}
and then use a closure that uses .call or .apply to bind el to this when it's invoked:
$('html, body').animate({
scrollTop: el.offset().top - 50
}, 1000, 'swing', callback ? function() {
callback.call(el);
} : undefined);
Everything works just fine, but when I remove
{queue:false, duration: 800, easing: 'easeInOutQuart'}
from
$(".chapters_list").slideDown(
with a 500, it stops working. So if I don't want easing in my script, it will work fine, when I insert easing into the top function, like is shown below, it stops working. Why wont it allow me to have easing?
$('.article_book_title').click(function () {
if ($(".chapters_list").is(":hidden")) {
$(".chapters_list").slideDown({queue:false, duration: 800, easing: 'easeInOutQuart'}, function () {
doSlide($('UL.chapters_list li:first'))
});
} else {
$(".chapters_list").slideUp({queue:false, duration: 800, easing: 'easeInOutQuart'});
}
});
function doSlide(current) {
$(current).animate({
backgroundColor:'#d6f4aa', color:'#eee'
},40, function() {
$(this).animate({backgroundColor:'#252525', color:'#fff'}, 500)
doSlide($(current).next('li'));
});
}
The shortcut methods like slideUp dont take an object config as an argument.. they take the duration and the call back. If you want more advance options you have to use the animate method.
slideUp API