2013-05-21 34 views
0

我有下面的代碼:遞歸調用函數返回的對象

// 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? 

     } 

    }; 
}; 

我想實現的是加在汽車移動下面的效果()函數:

$(img).animate({ 
    top: newTop, 
    left: newLeft, 
    }, 1000, function() { 
    automove(); /* recall */ 
    }); 

但如何從它的身體再次調用automove?也許我應該徹底改變在$ .zoom函數中聲明函數的方式嗎?

回答

1

如果你想遞歸調用automove()從內部自身傳統的方法是使用arguments.callee。因此,代碼會看起來像:

return { 

    /* ... */ 

    automove: function() { 

     $(img).animate({ 
      top: newTop, 
      left: newLeft, 
     }, 1000, 
     arguments.callee /* recall */ 
    ); 

    } 
} 

但在HTML5不贊成這種方式,實際上是在嚴格模式下是非法的。相反,你可以簡單地給該功能的名稱:

return { 

    /* ... */ 

    automove: function myAutomove() { // <-- give it a name 

     $(img).animate({ 
      top: newTop, 
      left: newLeft, 
     }, 1000, 
     myAutomove /* recall */ 
    ); 

    } 
} 

命名的函數表達式工作在新老所有的瀏覽器,並且更易於閱讀。


注:

如果一個函數不需要參數,你可以簡單地傳遞一個參考,以它作爲一個回調,而不是在一個匿名函數進行包裝的:

setTimeout(function(){ foo() },100); // <-- this is completely unnecessary 

setTimeout(foo,100); // <-- just need to do this instead 
1

嘗試

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