2013-04-30 41 views
1

我試圖與延伸的jQuery像這樣一個插件的工作:

$.extend({ 
    StatelessDeferred: function() { 
     var doneList = $.Callbacks("memory"), 
      promise = { 
      done: doneList.add, 

       // Get a promise for this deferred 
       // If obj is provided, the promise aspect is added to the object 
       promise: function (obj) { 
        var i, 
        keys = ['done', 'promise']; 
        if (obj === undefined) { 
        obj = promise; 
        } else { 
        for (i = 0; i < keys.length; i += 1) { 
         obj[keys[i]] = promise[keys[i]]; 
        } 
        } 
        return obj; 
       } 
      }, 
      deferred = promise.promise({}); 

      deferred.resolveWith = doneList.fireWith; 

     return deferred; 
     } 
    }); 

問題是(我甚至不能確定它的位置造成的),則回調加載後,一個done回調裏面,無論是this$(this)是一樣的,所以我最終舉例爲:this === $(this) === $(document)

我不太確定我瞭解什麼被擴展。除了錯誤的分配外,插件可以正常工作。

問:
能否上述延長是造成this === $(this) === $(document)

編輯: 全部插件(120lines):

"use strict"; 

(function (window, $) { 
    $.extend({ 
     StatelessDeferred: function() { 
     var doneList = $.Callbacks("memory"), 
      promise = { 
      done: doneList.add, 

      // Get a promise for this deferred 
      // If obj is provided, the promise aspect is added to the object 
      promise: function (obj) { 
       var i, 
       keys = ['done', 'promise']; 
       if (obj === undefined) { 
       obj = promise; 
       } else { 
       for (i = 0; i < keys.length; i += 1) { 
        obj[keys[i]] = promise[keys[i]]; 
       } 
       } 
       return obj; 
      } 
      }, 
      deferred = promise.promise({}); 

     deferred.resolveWith = doneList.fireWith; 

     // All done! 
     return deferred; 
     } 
    }); 

    var routes = [], 
    current_priority = 0, 
    methods = { 
     add: function (pattern, priority) { 
     var i = 0, 
      inserted = false, 
      length = routes.length, 
      dfr = $.StatelessDeferred(), 
      context = $(this), 
      escapepattern, 
      matchingpattern; 
     if (priority === undefined) { 
      priority = 0; 
     } 
     if (pattern !== undefined) { 
      // http://simonwillison.net/2006/Jan/20/escape/ 
      escapepattern = pattern.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 
      matchingpattern = escapepattern 
          .replace(/<int:\w+>/g, "(\\d+)") 
          .replace(/<path:\w+>/g, "(.+)") 
          .replace(/<\w+>/g, "([^/]+)"); 
      while (!inserted) { 
      if ((i === length) || (priority >= routes[i][2])) { 
       routes.splice(i, 0, [new RegExp('^' + matchingpattern + '$'), dfr, priority, context]); 
       inserted = true; 
      } else { 
       i += 1; 
      } 
      } 
     } 
     return dfr.promise(); 
     }, 
     go: function (path, min_priority) { 
     var dfr = $.Deferred(), 
      context = $(this), 
      result; 

     if (min_priority === undefined) { 
      min_priority = 0; 
     } 
     setTimeout(function() { 
      var i = 0, 
      found = false, 
      slice_index = -1, 
      slice_priority = -1; 
      for (i = 0; i < routes.length; i += 1) { 
      if (slice_priority !== routes[i][2]) { 
       slice_priority = routes[i][2]; 
       slice_index = i; 
      } 
      if (routes[i][2] < min_priority) { 
       break; 
      } else if (routes[i][0].test(path)) { 
       result = routes[i][0].exec(path); 
       dfr = routes[i][1]; 
       context = routes[i][3]; 
       current_priority = routes[i][2]; 
       found = true; 
       break; 
      } 
      } 
      if (i === routes.length) { 
      slice_index = i; 
      } 
      if (slice_index > -1) { 
      routes = routes.slice(slice_index); 
      } 
      if (found) { 
      dfr.resolveWith(
       context, 
       result.slice(1) 
      ); 
      } else { 
      dfr.rejectWith(context); 
      } 
     }); 
     return dfr.promise(); 
     }, 
    }; 


    $.routereset = function() { 
    routes = []; 
    current_priority = 0; 
    }; 

    $.routepriority = function() { 
    return current_priority; 
    }; 

    $.fn.route = function (method) { 
    var result; 
    if (methods.hasOwnProperty(method)) { 
     result = methods[method].apply(
     this, 
     Array.prototype.slice.call(arguments, 1) 
    ); 
    } else { 
     $.error('Method ' + method + 
      ' does not exist on jQuery.route'); 
    } 
    return result; 
    }; 

}(window, jQuery)); 

所以我可以用這個作爲一個路由器,並設置路徑,像這樣:

$(".element").add("route", "/foo/bar/<path:params>", 2).done(function(params){ 
    // do something, for example 
    console.log(this); 
    console.log($(this)); 
    console.log("which will be the same = $('.element')); 
}); 

希望它現在更清楚。

謝謝你看看。

+0

'$(this)'不可能是'==='到'$(document)',因爲那些對象是函數調用的結果。 – 2013-04-30 16:45:33

+0

讓我添加一些代碼。 1分鐘。 – frequent 2013-04-30 16:46:19

+0

當然。你是否在使用一個可以緩存藏品的插件? – 2013-04-30 16:49:38

回答

0

從文檔:

如果只有一個參數被供給到$ .extend(),這意味着該目標參數被刪去。在這種情況下,jQuery對象本身被假定爲目標。

大多數情況下,jQuery是連接到您的文檔具有:$(document).ready()

我認爲正在發生的事情是jQuery對象被包裹到文檔。然後你將它與$.extend(myObject)合併。這將返回一個既是jQuery對象又是myObject的單個對象。

+2

你能否就這個問題與這個問題相關提供一些解釋?謝謝。 – 2013-04-30 16:56:06

+0

hm。我會查的。感謝這個想法 – frequent 2013-04-30 17:06:53

相關問題