2011-08-13 10 views
7

Jak wybrać pierwsze "najciemniejsze" wejście?Jak wybrać "najkrótszego" pasującego potomka?

Mój bieżący wybór będzie działem oznaczonym "zaznaczony".
Nie będę wiedział, ile poziomów spadnie.

<div class="selected"> <!-- already have this --> 
    <div class="unknown-number-of-wrapper-panels"> 
    ... 
    <div class="collection">  
     <div class="child"> 
     <input type="text" value="2" /> <!-- don't want this --> 
     </div> 
    </div> 
    <input type="text" value="2" /> <!-- need this --> 
    <input type="text" value="2" /> 
    ... 
    </div> 
</div> 

Wygląda na to, że find().first() daje mi najgłębsze.

Edytowane dla zachowania przejrzystości. Muszę go znaleźć w oparciu o fakt, że jest on płytszy, a nie oparty na innych unikalnych atrybutach.

Może to być odwrotna strona niż closest()?

+0

'$ ('płytsze. Pierwszy')'? – knittl

+0

@knittl Przepraszam .. Właśnie umieściłem tam te klasy dla wyjaśnienia, może będę je edytować – Benjamin

+2

Poszukujesz najpierw szerokiego wyszukiwania, a nie pierwszego wyszukiwania w głębi (czego używa jQuery's find()). Szybki google znalazł: http://plugins.jquery.com/project/closestChild –

Odpowiedz

7

Jeśli rozumiem Twój problem, musisz rekurencyjnie sprawdzić węzły podrzędne pod kątem elementów z tą klasą.

function findShallowest(root, sel) { 
    var children = root.children(); 
    if(children.length) { 
     var matching = children.filter(sel); 
     if(matching.length) { 
      return matching.first(); 
     } else { 
      return findShallowest(children, sel); 
     } 
    } else { 
     return null; 
    } 
} 

var selected = $('.selected'); 

findShallowest(selected, ':text'); 

przykład:http://jsfiddle.net/Qf2GM/


Edycja: zapomniał oświadczenie powrotnego, i miał wyboru identyfikatora zamiast selektora klasy dla początkowego .selected.


Albo uczynić go swoim niestandardowym plugin:

Przykład:http://jsfiddle.net/qX94u/

(function($) { 
    $.fn.findShallowest = function(sel) { 
     return findShallowest(this, sel); 
    }; 
    function findShallowest(root, sel) { 
     var children = root.children(); 
     if (children.length) { 
      var matching = children.filter(sel); 
      if (matching.length) { 
       return matching.first(); 
      } else { 
       return findShallowest(children, sel); 
      } 
     } else { 
      return $(); 
     } 
    } 
})(jQuery); 

var result = $('.selected').findShallowest(':text'); 


alert(result.val()); 
+0

+1 - Zapraszam do wykradnięcia kodu z mojej odpowiedzi - usunę go po. Nice approach – gnarf

+0

Problem z tym miałem, że nie pozwalał na selektory atrybutów danych ... Aby to naprawić, edytowałem wywołanie filtra, aby użyć funkcji jittera .is, to: 'children.filter (function() { \t return $ (this) .is (sel); }); ' – MikingTheViking

3

Poszukiwane jest pierwsze wyszukiwanie, a nie pierwsze wyszukiwanie głęboka (używane przez jQuery's find()). Szybkie google znalazł: http://plugins.jquery.com/project/closestChild

ten może być wykorzystywany tak:

$(...).closestChild('input') 
0

Jeśli nie znasz nazwy klasy dolnym poziomie elementem zawsze można użyć coś jak

$('.unknown-number-of-wrapper-panels').children().last(); 
0

Dobrze biorąc pod uwagę twój znacznik, czy następująca praca?

$('.selected div > input:first') 
+0

Nie wiem. Czy to działa, biorąc pod uwagę, nie wiem, jak daleko wejście będzie na drzewie? Zapoznam się z tym. – Benjamin

+0

Szukasz wejścia, które jest bezpośrednim potomkiem rodzica, zamiast zagnieżdżać się dalej. To jest to, co zrobiłby div> input, lub $ ("div"). Children ('input') zamiast $ (' div '). find (' input '), który zwróci wszystkie wejścia, niezależnie czy jest to bezpośrednie dziecko diva czy nie –

1

Jest to kolejny podejście.Chodzi o to, że masz element pasujący z najmniejszą liczbą przodków:

(function($) { 
    $.fn.nearest = function(selector) { 
     var $result = $(); 
     this.each(function() { 
      var min = null, 
       mins = {}; 
      $(this).find(selector).each(function() { 
       var n_parents = $(this).parents().length,     
       if(!mins[n_parents]) { 
        mins[n_parents] = this; 
        min = (min === null || n_parents < min) ? n_parents : min; 
       }    
      }); 
      $result = $result.add(mins[min]); 
     }); 

     return $result; 
    }; 
}(jQuery)); 

Zastosowanie:

$('selected').nearest('input'); 

DEMO

findShallowest, as @patrick has it, może być lepszym nazwa metody;)

3

Tylko do gry w golfa - "Użycie" @user113716's technique, tylko zredukowany rozmiar kodu.

$.fn.findShallowest = function(selector) { 
    var children = this.children(), 
     matching = children.filter(selector); 
    // return an empty set if there are no more children 
    if (!children.length) { 
     return children; 
    } 
    // if anything matches, return the first. 
    if (matching.length) { 
     return matching.first(); 
    } 
    // check grand-children 
    return children.findShallowest(selector); 
}; 

przymierzyć jsFiddle

Powiązane problemy