2011-12-08 15 views
9

HTML:Perché jQuery restituisce un indice di 3?

<ul> 
    <li class="selected">First Item</li> 
    <li class="disabled">Second Item</li> 
    <li class="separator">Third Item</li> 
    <li>Fourth Item</li> 
</ul> 

jQuery:

alert($("li:not(.disabled,.separator)").index()); 

Secondo the documentation per l'indice:

il valore restituito è un numero intero che indica la posizione del primo elemento all'interno dell'oggetto jQuery relativo ai suoi elementi fratelli.

Enfasi su first element. Ma il codice sopra riportato restituisce 3. Sulla base della documentazione non dovrebbe questo codice restituire 0?

Potete vederlo in azione qui: http://jsfiddle.net/Zf9Vv/

NOTA:

mio selettore seleziona due elementi: il primo e l'ultimo LI.

+2

colpito il chiodo sulla testa. Hai scoperto una regressione. :) – Jon

+1

Yay per me !!! È possibile visualizzare il biglietto qui: http://bugs.jquery.com/ticket/10977 –

+0

Sulla base delle mie conclusioni (si veda [risposta] (http://stackoverflow.com/a/8424662/50079), penso che il il biglietto è fuorviante. Questa è una regressione introdotta in 1.6.3 e dovrebbe essere riportata come tale. Non c'è (ovviamente) nulla nelle note di rilascio 1.6.3 che indica che il comportamento documentato di 'index()' sarebbe cambiato. – Jon

risposta

5

Modifica (vedi commenti) La risposta originale non è corretta ... ho intenzione di tenerlo qui per ora in modo che i commenti hanno senso.

Guardando la fonte jQuery per index, si può vedere la following snippet:

if (!elem) { 
    return (this[0] && this[0].parentNode) ? this.prevAll().length : -1; 
} 

confronta questo al corrispondente (se molto diverso) frammento da una versione precedente, 1.6.2. Si noti l'uso di this[0]:

return jQuery.inArray(this[0], 
// If it receives a string, the selector is used 
// If it receives nothing, the siblings are used 
elem ? jQuery(elem) : this.parent().children()); 

Sembra che nella versione attuale la parte this.prevAll causa il problema. Se lo si cambia in this.eq(0).prevAll (che replica ciò che afferma la documentazione index), si ottiene il valore corretto restituito. Quindi sembrerebbe un bug jQuery.

Nella versione 1.6.2, viene utilizzato inArray. Questo metodo restituisce l'indice del primo argomento nel secondo argomento (o -1 se il primo argomento non viene trovato nel secondo). Poiché il primo argomento è this[0] (il primo elemento nel set abbinato) otteniamo il risultato previsto.

Ecco uno updated fiddle con la sorgente jQuery modificata inclusa. Il risultato corretto viene avvisato.


risposta originale (questo non è corretto):

leggere la parte citata dei documenti di nuovo con attenzione (evidenziazione in grassetto aggiunto):

il valore di ritorno è un intero che indica il posizione del primo elemento all'interno dell'oggetto jQuery relativo agli elementi di pari livello.

Solo perché due dei fratelli sono stati rimossi dal gruppo appaiato, ma non cambia il valore restituito da index. In altre parole, l'elemento corrispondente (<li>Fourth Item</li>) avrà sempre l'indice 3, relativo ai suoi fratelli (a meno che, naturalmente, i nuovi fratelli siano inseriti nel DOM prima dell'elemento in questione).

+2

Ma dal momento che il primo e l'ultimo 'LI' sono abbinati dovrebbe selezionare il primo (che ha un indice di 0)? –

+0

Ah, capisco cosa intendi. Lo esaminerò quindi non cancellerò ancora la mia risposta. –

+0

Stavo guardando lo stesso adesso, +1 per pubblicare i fatti. – Jon

4

È probabile che tu abbia trovato una discrepanza tra la funzionalità jQuery effettiva e ciò che dicono i documenti.

Il docs stato

Se nessun argomento viene passato al metodo .index(), il valore restituito è un numero intero che indica la posizione del primo elemento all'interno dell'oggetto jQuery rispetto al suo fratello elements.`

Tuttavia, .index() viene restituita l'indice dell'ultimo elementoall'interno dell'oggetto jQuery.

Questo può essere dimostrato (senza introdurre un potenziale problema con la: Non selettore) nel vostro violino per console.log($("li").index()); // 3

Forse è necessaria una segnalazione di bug su jQuery?

+1

** Persone, questo non è un problema di documentazione. È una regressione. ** – Jon

+0

Era diretto a me? Non ho detto che si trattava di un problema di documentazione, ma che si trattava di una discrepanza tra funzionalità e documenti effettivi. – simshaun

+0

E 'stato principalmente indirizzato agli uptoters della mentalità di herd, ma è applicabile anche a te, nel senso che la risposta lascia l'impressione che questo dovrebbe essere corretto cambiando la documentazione. – Jon

4

Aggiornamento:

confermati, questo è una regressione introdotta in jQuery 1.6.3. Le versioni precedenti mostrano il comportamento previsto (return 0).

Dopo aver indagato, sono arrivato con riluttanza alla conclusione che questo non può essere nient'altro che un bug in jQuery.

In particolare, in questo caso almeno, index() restituisce l'indice rispetto ai suoi fratelli del secondo elemento adattato (nuda <li>). Questo nonostante il fatto che

$("li:not(.disabled,.separator)").get(0) 

restituisce correttamente il <li class="selected">.

Inoltre, se cambiamo il selettore a

$("li:not(.disabled,.separator,:last-child)").index() 

poi index restituisce correttamente 0.

Prove eseguite usando jQuery 1.7.1

+0

Sì, dopo aver provato questo è davvero un bug in jQuery. Buona chiamata – Alex

+1

@Alex: ho testato e individuato 1.6.3 come versione colpevole. Ora scopriamo cosa è andato storto :) – Jon

+0

@Jon - Sembra che ciò che è andato storto sia una modifica da 'this [0]' a 'this' (tra molte altre modifiche - il codice è completamente diverso nell'ultima versione). Vedi la mia risposta (aggiornata). –

Problemi correlati