2016-01-03 14 views
11

Die Dokumentation für jQuerys closest sagt der folgende:jQuery .closest Standardkontext

.closest (Selektor [, context])
...
Kontext
Typ: Element
A DOM Element, in dem ein passendes Element gefunden werden kann. Wenn kein Kontext übergeben wird, wird stattdessen der Kontext des jQuery-Sets verwendet.

Wie ich es verstehe, bedeutet der fett gedruckten Text, dass die beiden Aussagen äquivalent sein sollte:

set.closest("a"); 

set.closest("a", set.context); 

wo set einige Jquery-Set.

jedoch, dies scheint nicht der Fall zu sein:

var context = $("#inner")[0]; 
 
var set = $("#el", context); 
 

 
// the set's context is correctly the "inner" element 
 
set.text("context: " + set.context.id); 
 

 
// if the set's context is used, this closest should match nothing, but it matches and sets the color 
 
set.closest("#outer").css("color", "red"); 
 

 
// with the context explicitly set, the "outer" is not found and no background color is set 
 
set.closest("#outer", set.context).css("background-color", "blue");
#outer{ 
 
    width: 100px; 
 
    height: 100px; 
 
    border: 1px solid black; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<div id="outer"> 
 
    <div id="inner"> 
 
    <div id="el"></div> 
 
    </div> 
 
</div>

Wie Sie sehen können, wenn kein Zusammenhang explizit festgelegt ist, wird das Set Kontext nicht zu sein scheint verwendet als #outer Element wird von closest gefunden. Wenn explizit festgelegt, wird #outer nicht korrekt gefunden.

Ist die Dokumentation falsch oder fehlt mir etwas?

+1

Ich denke, die Dokumentation ist falsch. Es sieht nicht so aus, als würde der Kontext des jQuery-Sets verwendet, wenn der Kontext nicht angegeben ist. –

+0

Warum hast du es gemacht 'var set = $ (" # el ", Kontext);'? Laut doc was ich bekomme, ist 'engest()', versuche den Ausdruck 'Selektor' an die Vorfahrenketten anzupassen, bis eine Übereinstimmung gefunden wird.Jetzt das zweite Argument die Methode 'engsten()' ist nur, um es ein Limit bis zu diesem Punkt zu geben, wird es weiter nach einem Spiel suchen. Und wenn es kein zweites Argument gibt, wird es von der JQuery entschieden, wo "body" das letzte Elternteil sein könnte. –

+0

Ihr Code sieht also nicht wie das richtige Beispiel für das Jquery-Dokument aus. –

Antwort

5

Dies ist eindeutig ein Fehler, und nicht, wie es beabsichtigt war zu arbeiten.

Die Quelle für closest() ist

function (selectors, context) { 
    var cur, 
     i = 0, 
     l = this.length, 
     matched = [], 
     pos = rneedsContext.test(selectors) || typeof selectors !== "string" 
      ? 
      jQuery(selectors, context || this.context) 
      : 
      0; 

    for (; i < l; i++) { 
     for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { 
      // Always skip document fragments 
      if (cur.nodeType < 11 && (pos ? pos.index(cur) > -1 : 

      // Don't pass non-elements to Sizzle 
      cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) { 

       matched.push(cur); 
       break; 
      } 
     } 
    } 

    return this.pushStack(matched.length > 1 ? jQuery.unique(matched) : matched); 
} 

Was die Art und Weise bemerkenswert ist, ist pos definiert ist, ist es die Sammlung für ein nächstes übergeordnetes Element gesucht zu werden ist, und rneedsContext ist die regex

/^[\x20\t\r\n\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\([\x20\t\r\n\f]*((?:-\d)?\d*)[\x20\t\r\n\f]*\)|)(?=[^-]|$)/i 

Wenn der übergebene Selektor stimmt nicht mit diesem Regex überein, es wird überhaupt kein Kontext verwendet, pos entspricht 0 und der Wert cur in dieser Auflistung wird einfach alle zusammen übersprungen, was mächtig seltsam erscheint.

Ein schneller Test zeigt

var reg = /^[\x20\t\r\n\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\([\x20\t\r\n\f]*((?:-\d)?\d*)[\x20\t\r\n\f]*\)|)(?=[^-]|$)/i; 

reg.test('#outer');  // false, no context used 
reg.test('#outer:first'); // true, context used 
reg.test('#outer:eq(0)'); // true, context used 

Also, wenn Sie einen Pseudo-Selektor hinzufügen, es plötzlich den Kontext verwendet?

Ich bezweifle, dass dies ist, was beabsichtigt war, und es scheint wie eine seltsame Sache zu tun, und es tut sicherlich nicht, was die Dokumentation sagt, dass es tun sollte.

+0

_" Die Quelle für am nächsten() ist "_ Welche Version ist Quelle bei post? Siehe http://stackoverflow.com/questions/34580013/jquery-closest-default-context/34580530#comment56906623_34580530 – guest271314

+0

@ guest271314 - das ist von 1.11.2, aber es ist das gleiche für alle etwas aktuellen Versionen – adeneo

+0

versuchten beide jsfiddles? Die Frage scheint spätestens beantwortet worden zu sein. Obwohl '.text()' nicht gesetzt ist? Oder lädt jsfiddle nicht zuletzt? JQuery-Objekt für 'DOM'-Element-Sets verwenden' background-color' 'set.closes (" # outer ", $ (set.context)). Css (" background-color "," blau ");' – guest271314