2010-05-13 13 views
101

El método transversal jQuery find(..) no incluye el nodo actual - comienza con los elementos secundarios del nodo actual. ¿Cuál es la mejor manera de llamar a una operación de búsqueda que incluye el nodo actual en su algoritmo de coincidencia? Mirando a través de los documentos, nada salta de inmediato hacia mí.Buscando el método jQuery find (..) que incluye el nodo actual

+1

Podría por favor, actualice la respuesta seleccionada en esta cuestión ahora que 'andSelf()' es obsoleto? –

+2

Hecho. Gracias @ChrisMarisic –

Respuesta

123

para jQuery 1.8 y arriba, puede utilizar .addBack(). Se necesita un selector de modo que no es necesario filtrar el resultado:

object.find('selector').addBack('selector') 

Antes de jQuery 1.8 a usted le toca .andSelf(), (ahora y eliminadas) que a su vez necesita de filtrado:

object.find('selector').andSelf().filter('selector') 
+4

He incluido esto como un plugin jquery.findIncludeSelf, registrado con bower. Consulte https://github.com/ronen/jquery.findIncludeSelf – ronen

+13

@ronen ¿Un archivo adicional para algo que se puede hacer en una línea? Gracias pero no gracias. –

+4

@ prc322 un archivo adicional no me molesta para las implementaciones que agrupan todos los javascript en un único archivo de todos modos. En general, prefiero usar métodos de biblioteca (probados) incluso para cosas simples, en lugar de saturar mi código con cosas que me resultan más difíciles de leer y que presentan más posibilidades de errores. En este caso en particular, en mi humilde opinión, la necesidad de especificar ''selector'' dos veces hace que la encapsulación sea más deseable. YMMV – ronen

1

creo andSelf es lo que quiere:

obj.find(selector).andSelf() 

Tenga en cuenta que esto siempre va a volver a agregar el nodo actual, si es o no coincide con el selector.

41

No se puede hacer esto directamente, lo más cerca que puedo pensar es el uso de .andSelf() y llamando .filter(), así:

$(selector).find(oSelector).andSelf().filter(oSelector) 
//or... 
$(selector).find('*').andSelf().filter(oSelector); 

Desafortunadamente .andSelf() no toma un selector, lo que sería muy útil.

+7

Incluso agregaste un comentario a la página de jquery justo después de responder a esta pregunta http://api.jquery.com/andSelf/#comment-50124533 Ahora bien, eso es minuciosidad. ¡Bonito! Hice mi diligencia debida y 'Me gustó' ese también. –

+2

El segundo sería alucinantemente lento. El primero es simplemente lento. – Tgr

+0

@Tgr - No estoy en desacuerdo, aunque el primero no debería ser ese programa a menos que se trate de * muy * gran cantidad de elementos. Si no necesita encadenar, puede omitir volver a filtrar esos elementos con seguridad. –

4
$('selector').find('otherSelector').add($('selector').filter('otherSelector')) 

Puede almacenar $('selector') en una variable para acelerar. Incluso puede escribir una función personalizada para esto si lo necesita mucho:

$.fn.andFind = function(expr) { 
    return this.find(expr).add(this.filter(expr)); 
}; 

$('selector').andFind('otherSelector') 
+0

Esto solo funciona si * está comenzando * con un selector, lo que puede no ser el caso. Además, es incorrecto, sería '$ ('selector'). Find ('otherSelector'). Add ($ ('otherSelector'))', lo que tienes ahora es equivalente a '.andSelf()'. Por último, '.andFind()' no se filtra según la expresión, necesitarías '.add ($ (this) .filter (expr))' :) –

+0

@Nick Craver: sí, olvidé el filtrado parte, arreglada ahora.Realmente no importa si '$ ('selector')' es reemplazado por algún otro método para obtener un objeto jQuery (si eso es lo que quisiste decir al no comenzar con un selector), 'add()' puede manejar cualquier cosa como '$()' puede. – Tgr

+0

Mi punto era que su '$ ('selector')' puede ser '$ ('selector'). Children ('filtro'). Más cercano ('. Class'). Last()' ... puede estar en una cadena y no tiene idea de qué es ese objeto que está agregando, por lo que la solución genérica debería tomar el objeto anterior como el filtro :) :) –

2

Sé que esta es una vieja pregunta, pero hay una manera más correcta. Si el orden es importante, por ejemplo, cuando se está a juego un selector como :first, escribí una pequeña función que devolverá el mismo resultado como si find() realidad incluido el actual conjunto de elementos:

$.fn.findAll = function(selector) { 
    var $result = $(); 

    for(var i = 0; i < this.length; i++) { 
    $result = $result.add(this.eq(i).filter(selector)); 
    $result = $result.add(this.eq(i).find(selector)); 
    } 

    return $result.filter(selector); 
}; 

No es va a ser eficiente por cualquier medio, pero es lo mejor que he encontrado para mantener el orden correcto.

-2

Aquí está el derecho (pero triste) la verdad:

$(selector).parent().find(oSelector).filter($(selector).find('*')) 

http://jsfiddle.net/SergeJcqmn/MeQb8/2/

+0

no funciona con nodos separados (y el documento en sí), sin embargo. –

+2

Uh, no, esto eliminará '$ (selector)' del conjunto en todos los casos. –

4

La respuesta aceptada es muy ineficiente y filtra el conjunto de elementos que ya están emparejados.

//find descendants that match the selector 
var $selection = $context.find(selector); 
//filter the parent/context based on the selector and add it 
$selection = $selection.add($context.filter(selector); 
4

Definir

$.fn.findSelf = function(selector) { 
    var result = this.find(selector); 
    return (this.is(selector)) ? 
     result.add(this) : result; 
}; 

a continuación, utilizar

$.findSelf(selector); 

en lugar de

$find(selector); 

Lamentablemente jQuery no tiene esta incorporado. Realmente extraño por tantos años de desarrollo.Mis controladores AJAX no se aplicaron a algunos elementos principales debido a cómo funciona .find().

2

Si desea que el encadenamiento funcione correctamente, utilice el siguiente fragmento.

$.fn.findBack = function(expr) { 
    var r = this.find(expr); 
    if (this.is(expr)) r = r.add(this); 
    return this.pushStack(r); 
}; 

Después de la llamada de la función final, devuelve el elemento #foo.

$('#foo') 
    .findBack('.red') 
     .css('color', 'red') 
    .end() 
    .removeAttr('id'); 

Sin definir los complementos adicionales, estás atascado con esto.

$('#foo') 
    .find('.red') 
     .addBack('.red') 
      .css('color', 'red') 
     .end() 
    .end() 
    .removeAttr('id'); 
0

Si está buscando estrictamente en el nodo (s) actual el que simplemente haces

$(html).filter('selector') 
0

Si estás buscando exactamente un elemento, ya sea elemento actual o uno dentro de ella , puede utilizar:

result = elem.is(selector) ? elem : elem.find(selector); 

Si estás buscando múltiples elementos que puede utilizar:

result = elem.filter(selector).add(elem.find(selector)); 

El uso de andSelf/andBack es bastante raro, no sé por qué. Tal vez debido a los problemas de rendimiento que algunos chicos mencionaron antes que yo.

(ahora se dio cuenta de que Tgr ya se dio esa segunda solución)

Cuestiones relacionadas