2011-12-08 21 views
9

HTML:¿Por qué jQuery devuelve un índice de 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()); 

Según the documentation para index:

el valor de retorno es un entero que indica la posición de la primera elemento dentro del objeto jQuery relativo a sus elementos hermanos.

Énfasis en first element. Pero el código anterior devuelve 3. Según la documentación, ¿este código no debe devolver 0?

Se puede ver en acción aquí: http://jsfiddle.net/Zf9Vv/

NOTA:

Mi selector equivale a dos elementos: el primero y el último LI.

+2

ha puesto el dedo en la cabeza. Usted ha descubierto una regresión. :) – Jon

+1

¡Yay para mí! Puede ver el ticket aquí: http://bugs.jquery.com/ticket/10977 –

+0

Basado en mis hallazgos (vea [respuesta] (http://stackoverflow.com/a/8424662/50079)), creo que el boleto es engañoso Esta es una regresión introducida en 1.6.3 y debe informarse como tal. No hay (por supuesto) nada en las notas de la versión 1.6.3 que indique que el comportamiento documentado de 'index()' habría cambiado. – Jon

Respuesta

5

Editar (ver comentarios) La respuesta original es incorrecta ... Voy a dejarlo aquí por ahora para que los comentarios tengan sentido.

En cuanto a la fuente de jQuery para index, se puede ver la following snippet:

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

comparar esto con el correspondiente (si es muy diferente) fragmento de una versión anterior, 1.6.2. Observe el uso de 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()); 

Parece que en la versión actual de la parte this.prevAll causa el problema. Si lo cambia a this.eq(0).prevAll (que replica lo que indica la documentación de index), se obtiene el valor correcto. Entonces parece que esto es un error jQuery.

En la versión 1.6.2, se usa inArray. Ese método devuelve el índice del primer argumento en el segundo argumento (o -1 si el primer argumento no se encuentra en el segundo). Como el primer argumento es this[0] (el primer elemento en el conjunto combinado) obtenemos el resultado esperado.

Aquí hay un updated fiddle con la fuente jQuery modificada incluida. El resultado correcto es alertado.


Respuesta original (esto es incorrecto):

Leer la parte citada de la documentación de nuevo con cuidado (el resaltado en negrita en el original):

el valor de retorno es un entero que indica la posición del primer elemento dentro del objeto jQuery en relación con sus elementos hermanos.

El hecho de que dos de los hermanos se hayan eliminado del conjunto combinado, no cambia el valor devuelto por index. En otras palabras, el elemento coincidente (<li>Fourth Item</li>) siempre tendrá el índice 3, relativo a sus hermanos (a menos que, por supuesto, se inserten nuevos hermanos en el DOM antes del elemento en cuestión).

+2

Pero dado que el primero y el último 'LI's coinciden, ¿debe seleccionar el primero (que tiene un índice de 0)? –

+0

Ahh, entiendo a qué te refieres. Voy a analizarlo para no eliminar mi respuesta todavía. –

+0

Estaba viendo lo mismo en este momento, +1 por publicar los hechos. – Jon

4

Es probable que haya encontrado una discrepancia entre la funcionalidad real de jQuery y lo que dicen los documentos.

El docs estado

Si no argumento se pasa al método .index(), el valor de retorno es un entero que indica la posición del primer elemento dentro del objeto jQuery relación a su hermano elements.`

Sin embargo, .index() devuelve el índice del último elementodentro del objeto jQuery.

Esto se puede demostrar (sin introducir un posible problema con el: no Selector) en su violín por console.log($("li").index()); // 3

Tal vez se necesita un informe de error en jQuery?

+1

** Gente, esto no es un problema de documentación. Es una regresión. ** – Jon

+0

¿Eso fue dirigido a mí? No dije que era un problema de documentación, pero que era una discrepancia entre la funcionalidad real y los documentos. – simshaun

+0

Se dirigió principalmente a los videntes de la mentalidad de rebaño, pero también se aplica a usted en el sentido de que la respuesta deja la impresión de que esto se debe solucionar al cambiar la documentación. – Jon

4

Actualización:

se confirma, esto es una regresión introducida en jQuery 1.6.3. Las versiones anteriores muestran el comportamiento esperado (return 0).

Después de investigar, a regañadientes he llegado a la conclusión de que esto no puede ser otra cosa que no sea un error en jQuery.

Específicamente, en este caso al menos, index() devuelve el índice relativo a sus hermanos del segundo elemento coincidente (el <li> desnudo). Esto a pesar del hecho de que

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

devuelve correctamente el <li class="selected">.

Por otra parte, si cambiamos el selector a

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

continuación index correctamente devuelve 0.

Las pruebas realizadas usando jQuery 1.7.1

+0

Sí, después de las pruebas esto es de hecho un error en jQuery. Buena llamada. – Alex

+1

@Alex: He probado y señalado 1.6.3 como el lanzamiento culpable. Ahora averigüemos qué salió mal :) – Jon

+0

@Jon - Parece que lo que salió mal es un cambio de 'this [0]' a 'this' (entre muchos otros cambios, el código es completamente diferente en la última versión). Ver mi respuesta (actualizada). –

Cuestiones relacionadas