2017-01-24 12 views
0

Ich hatte den Eindruck, dass closest() mir am nächsten passenden Element geben wird, wie es suggeriert, aber ich habe mich geirrt, es wird mir nächsten Vorfahren geben, so tut parents(). Wie kann ich das nächste Element bekommen?Finde das nächste Element, nicht am nächsten

z.B. Ich habe 2 div s wie unten

<div id="clickme"> 
    Click me 
</div> 
<div class="findme" style="display:none"> 
    Find me 
</div> 

was zu tun ist, wenn ich .findme mit Bezug mit #clickme erhalten möchten.

Kann ich etwas wie $('#click').helpfullFunctionThatGivesNearestElement('.findme')?

Oder muss ich gesamte DOM wie $('findme') scannen? aber es kann 100s von .findme dann wie werde ich am nächsten zu bestimmten Element finden?

aktualisieren

.findme kann überall in DOM sein.

+0

Haben Sie eine Beziehung zwischen oben Schlepptau Elemente? Oder sie können irgendwo platziert werden – Satpal

+0

@Satpal überall. Nur eine, die am nächsten ist, sollte ausgewählt werden. – Imad

+2

Wenn du _nearest_ sagst, meinst du vor oder nach 'clickme' oder den beiden? und wenn du eins vorher und eins nach dem von ihnen ausgewählt haben solltest? –

Antwort

1

Dies ist, wie rekursiv der DOM sieht aus wie durchquert.

ich implementiert haben die Funktion $.fn.nearest, als OP asumes jQuery zu verwenden, so kann es mit $('clickme').nearest('.findme');

Verfahren mehrere Elemente genannt werden, werden feststellen, ** (wenn sie die gleiche Abstand teilen von der Startknoten) durch Hin- und Herschau in jede Richtung (Eltern, Kinder, Nächste und Vorherige) durch rekursives Durchsuchen der nächsten überprüften Elemente. Es wird auch vermieden, ein Element immer wieder zu überprüfen (d. H. Das übergeordnete Element mehrerer untergeordneter Elemente wird nur einmal überprüft).

Wenn Sie keine bestimmte Richtung überprüfen möchten, d. H. children oder prev, können Sie diesen Teil einfach kommentieren.

Einige Überprüfungen werden durchgeführt, bevor die Rekursion durchgeführt wird. Wenn der Selektor nicht im DOM gefunden wird, wird ein leeres jQuery-Element zurückgegeben, auch wenn nur ein Element gefunden wurde, dass das gefundene Element zurückgegeben wurde.

Ich habe nicht getestet, es ist die Effizienz mit einem großen HTML, es hängt alles wie weit das gewünschte Element befindet, und das ist direkt mit der Komplexität der HTML-Struktur verbunden. Aber sicher ist es exponentiell, etwas in der Nähe von O (n³) oder O (n⁴).

Probieren Sie es aus.

$.fn.nearest = function(selector) { 
 
    var allFound = $(selector); 
 

 
    if (!allFound.length) // selector not found in the dom 
 
    return $([]); 
 

 
    if (allFound.length == 1) // found one elem only 
 
    return allFound; 
 
    else 
 
    return nearestRec($(this), selector); 
 

 
    function nearestRec(elems, selector) { 
 
    if (elems.length == 0) 
 
     return this; 
 

 
    var selector = selector; 
 
    var newList = [], 
 
     found = $([]); 
 

 
    $(elems).each(function(i, e) { 
 
     var options = e[1] || {}; 
 
     e = $($(e)[0]); 
 

 
     // children 
 
     if (!options.ignoreChildren) 
 
     updateFound(e.children(), selector, newList, found, { 
 
      ignoreParent: true 
 
     }); 
 

 
     // next 
 
     if (!options.ignoreNext) 
 
     updateFound(e.next(), selector, newList, found, { 
 
      ignoreParent: true, 
 
      ignorePrev: true 
 
     }); 
 

 
     // prev 
 
     if (!options.ignorePrev) 
 
     updateFound(e.prev(), selector, newList, found, { 
 
      ignoreParent: true, 
 
      ignoreNext: true 
 
     }); 
 

 
     // parent 
 
     if (!options.ignoreParent) 
 
     updateFound(e.parent(), selector, newList, found, { 
 
      ignoreChildren: true 
 
     }); 
 
    }); 
 

 
    return found.length && found || nearestRec(newList, selector); 
 

 
    function updateFound(e, selector, newList, found, options) { 
 
     e.each(function() { 
 
     var el = $(this); 
 
     if (el.is(selector)) { 
 
      found.push(el); 
 
      return; 
 
     } 
 

 
     newList.push([el, options]); 
 
     }); 
 
    } 
 
    } 
 
}; 
 

 

 
$(function() { 
 
    // multiple elems found, traverse dom 
 
    $(".clickme").nearest(".findme").each(function() { 
 
    $(this).addClass("found"); 
 
    }); 
 
});
div { 
 
    padding: 5px 3px 5px 10px; 
 
    border: 1px solid #666; 
 
    background-color: #fff; 
 
    margin: 3px; 
 
} 
 
.found { 
 
    background-color: red; 
 
} 
 
.clickme { 
 
    background-color: #37a; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="findme"> 
 
    findme 
 
    <div class="findme"> 
 
    findme 
 
    <div> 
 
     &nbsp; 
 
     <div> 
 
     &nbsp; 
 
     </div> 
 
     <div> 
 
     &nbsp; 
 
     </div> 
 
     <div class="clickme"> 
 
     clickme 
 
     <div> 
 
      &nbsp; 
 
     </div> 
 
     <div> 
 
      &nbsp; 
 
      <div class="findme"> 
 
      findme 
 
      <div class="findme"> 
 
       findme 
 
      </div> 
 
      </div> 
 
      <div class="findme"> 
 
      findme 
 
      </div> 
 
     </div> 
 
     </div> 
 
     <div> 
 
     &nbsp; 
 
     <div class="findme"> 
 
      findme 
 
     </div> 
 
     </div> 
 
     <div class="findme"> 
 
     findme 
 
     </div> 
 
    </div> 
 

 
    <div class="findme"> 
 
     findme 
 
     <div> 
 
     &nbsp; 
 
     </div> 
 
     <div> 
 
     &nbsp; 
 
     </div> 
 
     <div class="findme"> 
 
     findme 
 
     <div class="findme"> 
 
      findme 
 
     </div> 
 
     </div> 
 
     <div> 
 
     &nbsp; 
 
     </div> 
 
     <div class="findme"> 
 
     findme 
 
     </div> 
 
    </div> 
 
    </div> 
 
</div>

-1

Anstatt den gesamten DOM-Baum zu durchlaufen, können Sie versuchen, ein Element mit Bezug auf sein umschließendes Elternelement zu lokalisieren.

<div> 
<div id="clickme" onclick="$(this).parent().find('.findme').show();"> 
    Click me 
</div> 
<div class="findme" style="display:none"> 
    Find me 
</div> 
</div> 

Dies funktioniert jedoch nur, wenn das Element, das Sie suchen, einen übergeordneten Vorgänger hat.

+0

Dies funktioniert nicht, wenn das zweite übergeordnete Element das _nearest_ übereinstimmende Element ist, wie angegeben: _.findme kann überall in DOM._ –

0

jQuery-Plugin:

(function($){ 
    $.fn.nextElementInDom = function(selector, options) { 
     var defaults = { stopAt : 'body' }; 
     options = $.extend(defaults, options); 

     var parent = $(this).parent(); 
     var found = parent.find(selector + ":first"); 

     switch(true){ 
      case (found.length > 0): 
       return found; 
      case (parent.length === 0 || parent.is(options.stopAt)): 
       return $([]); 
      default: 
       return parent.nextElementInDom(selector); 
     } 
    }; 
})(jQuery); 

Verbrauch:

$('#clickme').nextElementInDom('.findme'); 
+0

Dieser Code wird ein passendes Kind der dritten Ebene vor einer zweiten Ebene finden übereinstimmenden Eltern –

+0

Können Sie bitte geben ein Beispiel oder Code-Snippet? – mhshimul

+0

einfach ... https://jsfiddle.net/8twn11tv/1/, noch mehr .. es wird ein n-tes Level-Kind vor dem zweiten Elternteil finden –

Verwandte Themen