2010-11-01 105 views
1

通常當你調用root.find('.test'),它會與test類返回內部root所有元素。有什麼方法可以考慮root作爲可能的候選人嗎?非標準find方法

換言之,與HTML

<div id="x" class="test"></div> 

$('#x').find('.test')將返回1個元件而不是零。

如果我們推廣它,在表達式root.find('condition1 condition2 condition3')我想condition1也針對root進行測試。

我正在考慮創建一個自定義幫助器方法,但也許有更優雅的東西。

謝謝!

回答

8

有這樣做沒有乾淨方式,你可以得到的最接近的是使用.andSelf()這樣的:

$('#x').find('.test').andSelf().filter('.test') 

這將是稍微乾淨(和更有效的,沒有雙濾波)如果.andSelf()了一個選擇器,但只會縮短一點。

與內置方法的最快(但有點混亂)的方式包括複製的ID選擇,就像這樣:

$('#x').find('.test').add($('#x').filter('.test')); 
//or, shorter but slower: 
$('#x').find('.test').add($('#x.test')); 

You can compare the performance of all 3 here

+1

+1,在我的大腦了黑客這一塊之後,這是唯一的很好的方式來做到這一點。 – Stephen 2010-11-01 19:46:01

+0

@Stephen我不會稱這個怪物爲'nice':)無論如何,看起來尼克是正確的,並沒有直接的解決方案。 – 2010-11-01 19:58:47

+0

@Nikita - 你在尋找一個元素還是很多? – 2010-11-01 20:03:09

1

爲了澄清什麼,我想你問...你想.find('.test a')僅搜索a如果您正在搜索的元素已經是.test ...

這是我在這個功能的嘗試:

$.fn.search = function(selector) { 
    selector = selector || ''; 
    var parts = selector.split(/\s+/), 
     l = parts.length, 
     iAm = '', 
     find = ''; 
    for (var x = l; x > 0; x--) { 
     // countning backwards from the end of the list 
     iAm = parts.slice(0, x).join(' '); 
     find = parts.slice(x).join(' '); 
     // if the 'iAm' portion of the selector matches this element 
     if (this.is(iAm)) { 
      // if there is no find portion (because we are the full selector) return ourself 
      // but add the children that also match the last portion of the selector 
      if (!find) return this.add(this.find(parts.slice(l-1).join(''))); 
      // return the .find() using only the parts of the selector needed 
      return this.find(find); 
     } 
    } 

    // otherwise, resort to original .find() 
    return this.find(selector); 
} 

And the test fiddle

當然,因爲這個方式分割了選擇部分(.split(/\s+/))它要打破對於含有S選擇在他們的步伐因其他原因像.something:has(.another .thing).something[value='1 2']類型選擇無法使用該功能

+0

+1你的答案(和尼克),它會給我一些東西來鍛鍊我的大腦:) – 2010-11-01 20:14:29

+0

這在其他情況下不起作用,例如:http://www.jsfiddle.net/nick_craver/ uCQ3P/ – 2010-11-01 20:15:28

+0

@尼克 - 好點...我認爲另一種解決方案效果更好一些,但這是一種可能的實現方法。 – gnarf 2010-11-01 20:19:04

1

我想你的情況下使用了這樣的事:

<div class="this"> 
    <div class="is" id="test"> 
     <div class="a"> 
      <div class="test"> 
      </div> 
     </div> 
    </div> 
</div> 

而且你有var $test = $('#test')。 你想要$test.find('.this .is .a .test')並獲得該內部div的參考。

$.fn.search = function(selector) { return this.find('*').andSelf().filter(selector); } 

然後你可以$test.search('.this .is .a .test')並得到一個內部div的引用! Demonstrated in this fiddle

當然,這是比只有.find()正確的選擇... ...

+0

順便說一句,你以前的答案有什麼問題?你正確地發現了我的意圖,我正在測試它。 – 2010-11-01 20:08:23

+0

這個代碼是小得多,並會返回相同的東西;) - 舊的答案可能會更快一點雖然...很難說... – gnarf 2010-11-01 20:09:49

+0

這很有趣,我不知道'過濾器'這樣的作品!讓我試試看。 – 2010-11-01 20:11:18

1

使用動態父級並找到它的內容。這可以包裝在一個插件中。

$('#x').wrap('<div />').parent() 
    .find('.test').css('margin-left', '20px') // affected have m-left: 20 
.end().children().unwrap(); 

fiddle example