Reputation: 739
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?
Upvotes: 2
Views: 2191
Reputation: 339786
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);
Upvotes: 2
Reputation: 1074168
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
.
Upvotes: 3