Tengo una etiqueta A que activa la animación de su tatarabuelo. Todo lo siguiente funcionará, pero ¿cuál es más eficiente y por qué?
$(this).parent().parent().parent().parent().parent().animate(...);
$(this).parents(".foo").animate(...);
$(this).closest(".foo").animate(...);
Sospecho que el primero podría serlo, ya que es el más explícito, pero por razones de mantenimiento (el anidamiento puede cambiar) prefiero el segundo. Todos ellos Aparecer funcionar sin problemas en la práctica.
Aquí hay un análisis:
parent()
camina solo un nivel hacia arriba en el árbol DOM.parents(".foo")
camina hasta la raíz y selecciona solo aquellos elementos que coinciden con el selector dado.foo
.closest(".foo")
camina hasta la raíz pero se detiene una vez que un elemento coincide con el selector.foo
.
Así que elegiría el último, closest(".foo")
. La razón:
- es mejor que encadenar
parent
porque si su documento cambia porque eliminó o agregó una jerarquía, no necesita cambiar el código jQuery. - Es mejor que
parents(".foo")
porque se detiene tan pronto como se encuentra una coincidencia.
Plippie
Bueno, el más cercano solo es útil si está subiendo o al mismo nivel en el elemento ‘pulsado’.
Si, por ejemplo, tiene que seguir el siguiente escenario:
<div class="controls radio-other">
<label class="radio"><input type="radio" name="item">Option one</label>
<label class="radio"><input type="radio" name="item">Option two</label>
<label class="radio"><input type="radio" name="item" class="other-option" data-othertarget="#otherone"> Other... </label>
<input type="text" placeholder="Alternative answer" id="otherone" class="hidden">
</div>
Después closest('#otherone')
no encontrará el campo de texto oculto en $('.other-option').click()
La mejor solución en este escenario es usar $(this).parentsUntil('.radio-other').find('#otherone')
Mirando mi respuesta hice una jsperf aquí que refleja el escenario anterior con diferentes soluciones. Simplemente use lo que sea más útil para su escenario html. el resultado es que parent().parent()
es el método más rápido, sin embargo, esta no siempre es una buena opción si su html es más flexible en uso. Agregue un padre div y el parent().parent()
se rompe
Es muy bueno que haya realizado mediciones de rendimiento. Eso es exactamente lo que se debe hacer en tales escenarios. Si todo parece funcionar sin problemas en la práctica y está satisfecho con el rendimiento, elija el más legible (el segundo y el tercer vistazo están bien).
Creo que vi una presentación de John Resig diciendo que close() está más optimizado y tiene cierto sentido. Closest() es una adición más reciente a jQuery y viene a resolver exactamente esta fea cadena parent().parent(). Por otro lado, parents() devuelve una matriz de padres que coinciden con su clase foo y es más codicioso en términos de búsqueda en comparación con más cercano() que encuentra el primer elemento y deja de buscar.
Apuesto a que más cercano () es el más eficiente si está buscando la coincidencia más cercana.
No puedo comentar sobre la velocidad real, sin embargo, la primera te vincula a una jerarquía específica de elementos, de la que me alejaría.
Personalmente, trato de usar los selectores de clase con moderación de todos modos. Me doy cuenta de que a menudo no hay otra manera, pero si puedo tener en cuenta un selector de ID, entonces sé que es probable que el rendimiento mejore de todos modos.
Ionus Staicu
También puedes usar parents('.foo:first')
. Supongo que es más o menos lo mismo que closest()
.
WynandB
Una prueba rápida en Firefox 3.6.3 revela que parents('.foo').eq(0)
en realidad es significativamente más rápido que closest('.foo')
. Es discutible si es tan mantenible, pero podría resultar más “eficiente” en escenarios específicos.
-
Si solo apunta a la velocidad, no debe usar la fachada jQuery en absoluto, sino simplemente atravesar DOM:
$(this.parentNode.parentNode.parentNode.parentNode.parentNode).animate(…)
– Gumbo
29 de abril de 2010 a las 7:26
Creo que respondiste tu propia pregunta allí. Si es lo suficientemente suave, no micro-optimice si la mantenibilidad se vería tan afectada. 🙂
– deceze
♦
15 de febrero de 2010 a las 9:39