2013-05-14 84 views
1

UPDATE 當前的解決方案就住在這主旨的情況下,你需要這種類型的功能 https://gist.github.com/jdaly13/5581538#file-gistfile1-js壓倒一切的jQuery .END()方法來接受參數

我想一個小實驗,我」米試圖重寫jQuery的核心方法到底用我自己的方法,它本質上只是將功能添加到它

例如,如果你正在使用jQuery你可以做這樣的事情

$('h1.clickme').click(function() { 
    $(this).next('div').css("width", "+=200").parent().next().hide().end().end() 
     //this should traverse you back to the div after the h1 clicked 
}) 

我希望通過添加添加一些參數 例如

.end(1) 

會做同樣的

.end().end() 

這裏的能力覆蓋了jQuery最終方法是我到目前爲止

(function(){ 

// Define overriding method. 
jQuery.fn.end = function(no_of_times){ 
    var prevObject = "prevObject"; 
    if (!(arguments.length) || (typeof no_of_times !== "number")) { 
     return this.prevObject || this.constructor(null); 
    } else { 
     if (no_of_times == 1) { 
      return this.prevObject.prevObject || this.constructor(null) 
     } else if (no_of_times == 2) { 
      return this.prevObject.prevObject.prevObject || this.constructor(null) 
     } else if (no_of_times == 3) { 
      return this.prevObject.prevObject.prevObject.prevObject || this.constructor(null) 
     } else { 
      //too many times can't type anymore 
      return this.prevObject || this.constructor(null); 
     }   
    } 

} 
})() 

所以我可以這樣打電話

$('.promo-carousel').parent().prev().siblings('span').hide().end(2) 

但是,顯然我不認爲這是有效的寫出所有這些if語句 有沒有更簡單的方法來做到這一點?我敢肯定的表現是差不多的,但

我想基於參數「prevObject」字符串追加prevObject可變的,我這樣做更多的可讀性起見順利通過這樣的

if (!(arguments.length) || (typeof no_of_times !== "number")) { 
      return this.prevObject || this.constructor(null); 
     } else { 
      for (i=0; i <= no_of_times; i++) { 
       pObj += "prevObject."   
      } 
      var prevObject = pObj.slice(0, prevObject.length -1) 
      console.log(prevObject); 
      return this.prevObject 
     } 

    } 

但代碼段以上沒有工作 任何幫助表示讚賞一如既往

+1

小心......我很確定'.prevObject'不是一個記錄的功能。你爲什麼不用一個不同的名字緩存原始的'.end()'並且調用它?或者更好的是,爲您的自定義方法使用不同的名稱。 – 2013-05-14 21:50:05

+0

同意 - 如果一個插件和一個新方法可以做,就沒有理由重寫'.end()'。 – Blazemonger

+0

是的,你可能是正確的 - 我只是想我添加功能,並沒有真正覆蓋它,所以它仍然會以同樣的方式工作,無論你是否添加參數 –

回答

2

這應該做的伎倆:

var prevObject = this.prevObject; 

for(i = 1; i<no_of_times; i++) { 
    prevObject = prevObject.prevObject; 
    if(!prevObject) { 
     prevObject = this.constructor(null); 
     break 
    } 
} 

只需獲取prevObjectprevObject循環的每次迭代,直到找不到prevObject

+0

謝謝艾略特工作 - 我知道我錯過了一些小事情意思就是在變量中存儲this.prevObject是最好的解決方案 –

1

類似的東西應該工作。

var prevObject = this.prevObject; 
for(i = 0; i<no_of_times; i++) { 
    prevObject = prevObject.prevObject; 
} 
return prevObject || this.constructor(null); 
+0

感謝您的答案 - 它非常接近Elliot的版本,但可讀性更簡單,我總是欣賞,所以我給了upvote –

+0

不客氣! – droidpl

0

你可以只重用舊的方法,你要重寫:

(function($){ 
    var oldfn = $.fn.end; 
    $.fn.end = function(times){ 
     times = times || 1; // default to 1 if nothing or 0 is passed in 
     var ret = this; 
     for (i=0;i<times;i++) { 
      ret = oldfn.call(ret); 
     } 
     return ret; 
    }; 
})(jQuery); 
1

這裏是我的解決方案:http://jsfiddle.net/QVxqY/
您不必重新實現任何邏輯或保持現有的元素軌跡:

(function($){ 
    var originalEnd = $.fn.end; 
    $.fn.end = function(n){ 
     if(!n) 
      return originalEnd.call(this); 
     return $.fn.end.call(originalEnd.call(this), n-1); 
    } 
})(jQuery); 
+0

非常酷的祗園,我甚至不會這樣想;非常好 - 我在這裏清理了一下你的語法http://jsfiddle.net/QVxqY/3/ –