Reputation: 5971
I have the following piece of code:
// Core Zoom Logic, independent of event listeners.
$.zoom = function(target, source, img) {
var outerWidth,
outerHeight,
xRatio,
yRatio,
offset,
position = $(target).css('position');
// This part of code is omitted
return {
init: function() {
outerWidth = $(target).outerWidth();
outerHeight = $(target).outerHeight();
xRatio = (img.width - outerWidth) / $(source).outerWidth();
yRatio = (img.height - outerHeight) / $(source).outerHeight();
offset = $(source).offset();
},
move: function (e) {
var left = (e.pageX - offset.left),
top = (e.pageY - offset.top);
top = Math.max(Math.min(top, outerHeight), 0);
left = Math.max(Math.min(left, outerWidth), 0);
img.style.left = (left * -xRatio) + 'px';
img.style.top = (top * -yRatio) + 'px';
},
automove: function() {
// can I recall this?
}
};
};
What I want to achieve is to add the following effect in automove() function:
$(img).animate({
top: newTop,
left: newLeft,
}, 1000, function() {
automove(); /* recall */
});
But how to call automove again from it's body? Maybe I should completely change the way functions are declared in $.zoom function?
Upvotes: 0
Views: 123
Reputation: 113866
If you want to recursively call automove()
from inside itself the traditional method would be to use arguments.callee. So the code would look something like:
return {
/* ... */
automove: function() {
$(img).animate({
top: newTop,
left: newLeft,
}, 1000,
arguments.callee /* recall */
);
}
}
But in HTML5 this is deprecated and is actually illegal in strict mode. Instead you can simply give the function a name:
return {
/* ... */
automove: function myAutomove () { // <-- give it a name
$(img).animate({
top: newTop,
left: newLeft,
}, 1000,
myAutomove /* recall */
);
}
}
Named function expression works in all browsers old and new and is much easier to read.
note:
If a function does not require parameters you can simply pass a reference to it as a callback instead of wrapping it in an anonymous function:
setTimeout(function(){ foo() },100); // <-- this is completely unnecessary
setTimeout(foo,100); // <-- just need to do this instead
Upvotes: 1
Reputation: 388316
Try
$.zoom = function(target, source, img) {
var outerWidth,
outerHeight,
xRatio,
yRatio,
offset,
position = $(target).css('position');
// This part of code is omitted
var fnInit = function() {
outerWidth = $(target).outerWidth();
outerHeight = $(target).outerHeight();
xRatio = (img.width - outerWidth) / $(source).outerWidth();
yRatio = (img.height - outerHeight) / $(source).outerHeight();
offset = $(source).offset();
};
var fnMove = function (e) {
var left = (e.pageX - offset.left),
top = (e.pageY - offset.top);
top = Math.max(Math.min(top, outerHeight), 0);
left = Math.max(Math.min(left, outerWidth), 0);
img.style.left = (left * -xRatio) + 'px';
img.style.top = (top * -yRatio) + 'px';
};
var fnAutomove = function() {
$(img).animate({
top: newTop,
left: newLeft,
}, 1000, function() {
fnAutomove(); /* recall */
});
}
return {
init: fnInit,
move: fnMove,
automove: fnAutomove
};
};
Upvotes: 1