1. Code
  2. JavaScript
  3. jQuery

Selectores jQuery Poco Comunes

Los selectores son de vital importancia. La mayoría de los métodos de jQuery requieren de algún tipo de selección de elemento para ser de cualquier utilidad. Por ejemplo, adjuntando un evento click a un botón requiere que selecciones el botón primero.
Scroll to top

Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)

Los selectores son de vital importancia. La mayoría de los métodos de jQuery requieren de algún tipo de selección de elemento para ser de cualquier utilidad. Por ejemplo, adjuntando un evento click a un botón requiere que selecciones el botón primero.

Ya que los selectores jQuery están basados en selectores CSS existentes, podrías estar bien versado en estos. Sin embargo, también hay unos cuantos selectores que no son tan usados. En este tutorial, me enfocaré en estos selectores menos conocidos pero importantes.

Selector All (*)

Este selector es correctamente llamado el selector universal porque selecciona todos los elementos en el documento, incluyendo las etiquetas <head>, <body>, <script> o <link>. or  Este demo debería ilustrar mi punto.

1
$("section *")         // Selects all descendants

2
$("section > *")       // Selects all direct descendants

3
$("section > * > *")   // Selects all second level descendants

4
$("section > * > * a") // Selects 3rd level links

Este selector es extremadamente lento si se usa en combinación con otros elementos. Sin embargo, todo depende en cómo el selector es usado y en cuál es ejecutado. En Firefox $("#selector > *").find("li") es más lento que  $("#selector > ul").find("li"). De manera interesante, Chrome ejecuta $("#selector > *").find("li") ligeramente más rápido. Todos los navegadores ejecutan $("#selector *").find("li") más lento que $("#selector ul").find("li"). Yo sugeriría que compares el rendimiento antes de usar este selector.

Aquí está un demo que compara la velocidad de ejecución del selector all.

Selector Animado (:animated)

Puedes usar el selector :animated para seleccionar todos los elementos cuya animación aún esté en progreso cuando este selector se ejecuta. El único problema es que solo seleccionará elementos que fueron animados usando jQuery. Este selector es una extensión de jQuery y no se beneficia de los impulsos de rendimiento cuando se trata del método nativo querySelectorAll().

También, no puedes detectar animación CSS usando jQuery. Puedes, sin embargo, detectar cuando la animación temina usando el evento animationend.

Echa un vistazo al siguiente demo.

En el demo de arriba, solo los elementos div impares son animados antes de ejecutar $(":animated").css("background","#6F9");. Como resultado, solo esos elementos div cambian a verde. Justo después de eso, podemos llamar la función animate sobre el resto de los elementos div. Si das clic al button ahora, todos los elementos div deberían volverse verdes.

Selector Atributo No Igual ([attr!="value"])

Los selectores de atributo común usualmente detectan si un atributo con un nombre o valor dado existe. Por otro lado, el selector [attr!="value"] detectará todos los elementos que no tienen el atributo especificado o en donde el atributo existe pero no es igual a un valor particular. Es equivalente a :not([attr="value"]). A diferencia de [attr="value"] , [attr!="value"] no es parte de la especificación CSS. Como resultado, usar $("css-selector").not("[attr='value']") puede mejorar el desempeño en navegadores modernos.

El pedazo de código agrega la clase mismatch a todos los elementos li cuyo atributo data-category no sea igual a css. Esto puede ser de utilidad cuando se depura o establece el valor de atributo correcto usando JavaScript.

1
$("li[data-category!='css']").each(function() {
2
  $(this).addClass("mismatch");
3
  // Adds a mismatch class to filtered out selectors.

4
  
5
  $(".mismatch").attr("data-category", attributeValue);
6
  // Set correct attribute value

7
});

En el demo, recorro dos listas y corrijo el valor de los atributos de categoría de los elementos.

Selector Contiene (:contains(text))

Este selector es usado para seleccionar todos los elementos que contienen la cadena especificada. La cadena con coincidencia puede estar directamente dentro del elemento o dentro de cualquiera de sus descendientes.

El ejemplo de abajo debería ayudarte a tener un mejor entendimiento de este selector. Estaremos agregando un fondo amarillo a todas las ocurrencias de la frase Lorem Ipsum.

Comencemos con el marcado:

1
<section>
2
  <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It
3
    has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.</p>
4
  <p>It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of <b>Lorem Ipsum</b>.</p>
5
  <a href="https://en.wikipedia.org/wiki/Lorem_ipsum">Lorem Ipsum Wikipedia Link</a>
6
</section>
7
<section>
8
  <p>This <span class="small-u">lorem ipsum</span> should not be highlighted.</p>
9
</section>
10
<ul>
11
  <li>A Lorem Ipsum List</li>
12
  <li>More Elements Here</li>
13
</ul>

Observa que la frase Lorem Ipsum ocurre en siete diferentes ubicaciones. He usado minúsculas de manera deliberada en una de estas instancias para mostrar que el emparejamiento es sensible a las mayúsculas.

Aquí está el código JavaScript para resaltar todas las coincidencias.

1
$("section:contains('Lorem Ipsum')").each(function() {
2
  $(this).html(
3
      $(this).html().replace(/Lorem Ipsum/g, "<span class='match-o'>Lorem Ipsum</span>")
4
    );
5
});

Las comillas alrededor de la cadena son opcionales. Esto implica que tanto $("section:contains('Lorem Ipsum')") como $("section:contains(Lorem Ipsum)") serán validos en el código de arriba. Solo estoy orientando el elemento section, así que el Lorem Ipsum dentro de los elementos de lista permanecerán sin cambios. Además, debido a mayúsculas no coincidentes, el texto dentro del segundo elemento section no debería ser resaltado tampoco. Como puedes ver en este demo, esto es exactamente lo que sucede.

Selector Has (:has(selector))

Este selector seleccionará todos los elementos que contengan al menos un elemento que coincida con un selector dado. El selector que necesita ser emparejado no tiene que ser un hijo directo. :has no es parte de la especificación CSS. En navegadores modernos, deberías usar $("pure-css-selector").has(selector) en vez de $("pure-css-selector:has(selector)") para rendimiento mejorado.

Una posible aplicación de este selector es la manipulación de elementos que contengan un elemento específico dentro de ellos. En nuestro ejemplo, estaré cambiando el color de todos los elementos de lista que contengan un enlace dentro de ellos.

Aquí está el marcado para el demo:

1
<ul>
2
  <li>Pellentesque <a href="dummy.html">habitant morbi</a> tristique senectus.</li>
3
  <li>Pellentesque habitant morbi tristique senectus.</li>
4
  (... more list elements here ...)
5
  <li>Pellentesque habitant morbi tristique senectus.</li>
6
  <li>Pellentesque <a href="dummy.html">habitant morbi</a> tristique senectus.</li>
7
</ul>

Aquí está el código JavaScript para cambiar el color de los elementos de lista:

1
$("li:has(a)").each(function(index) {
2
  $(this).css("color", "crimson");
3
});

La lógica detrás de este código es bastante sencilla. Ciclo todos los elementos de lista que contengan un enlace y establezco su color a carmesí. También podrías manipular el texto dentro de los elementos de lista o removerlos del DOM. Estoy seguro de que este selector puede ser usado en muchas otras situaciones. Revisa una versión en vivo de este código en CodePen.

Selectores Basados en Índices

Ademas de selectores CSS como :nth-child(), jQuery también tiene su propio conjunto de selectores basados en índices. Estos selectores son :eq(index):lt(index), y :gt(index). A diferencia se selectores basados en CSS, estos selectores usan índices basados en cero. Esto implica que mientras :nth-child(1) seleccionará el primer hijo, :eq(1) seleccionará el segundo hijo. Para seleccionar el primero hijo tendrás que usar :eq(0).

Estos selectores también pueden aceptar valores negativos. Cuando se especifican valores negativos, el conteo es realizado hacia atrás comenzando desde el último elemento.

:lt(index) selecciona todos los elementos que están en un índice menor que el valor especificado. Para seleccionar los primeros tres elementos, usarás :lt(3). Esto es porque los tres primeros elementos tendrás valores de índice 0, 1 y 2 respectivamente. Usar un índice negativo seleccionará todos los valores antes del elemento que alcanzamos después de contar hacia atrás. De manera similar, :gt(index) selecciona todos los elementos con índice mayor al valor especificado.

1
:lt(4)  // Selects first four elements
2
:lt(-4) // Selects all elements besides last 4
3
:gt(4)  // Selects all elements besides first 5
4
:gt(-4) // Selects last three elements
5
:gt(-1) // Selects Nothing
6
:eq(4)  // Selects fifth element
7
:eq(-4) // Selects fourth element from last

Intenta dar clic sobre varios botones en el demo para obtener un mejor entendimiento de selectores de índice.

Selectores de Formulario

jQuery define muchos selectores para selección sencilla de elementos de formulario. Por ejemplo, el selector :button seleccionará todos los elementos botón así como los elementos con tipo botón. De manera similar, :checkbox seleccionará todos los elementos input con tipo checkbox. Hay selectores definidos para casi todos los elementos input. Considera el formulario de abajo:

1
<form action="#" method="post">
2
  <div>
3
    <label for="name">Text Input</label>
4
    <br>
5
    <input type="text" name="name" />
6
    <input type="text" name="name" />
7
  </div>
8
  <hr>
9
  <div>
10
    <label for="checkbox">Checkbox:</label>
11
    <input type="checkbox" name="checkbox" />
12
    <input type="checkbox" name="checkbox" />
13
    <input type="checkbox" name="checkbox" />
14
    <input type="checkbox" name="checkbox" />
15
  </div>
16
</form>

He creado dos elementos de texto aquí y cuatro checkboxes. Este formulario es bastante básico, pero te debería dar una idea de cómo funcionan los selectores de formulario. Contaremos el número de elementos de texto usando el selector :text y también actualizaremos el texto en el primer input de texto.

1
var textCount = $(":text").length;
2
$(".text-elements").text('Text Inputs : ' + textCount);
3
4
$(":text").eq(0).val('Added programatically!');

Uso :text para seleccionar todos los input de texto y después el método length para calcular su número. En la tercera declaración uso el selector previamente discutido :eq() para acceder al primero elemento y después establecer su valor.

Ten en mente que desde jQuery 1.5.2, :text devuelve true para elementos que no tienen ningún tipo de atributo especificado.

Echa un vistazo al demo.

Selector Header (:header)

Si alguna vez quieres seleccionar todos los elementos header en una página web, puedes usar la versión corta $(":header") en lugar del selector $("h1 h2 h3 h4 h5 h6"). Este selector no es parte de la especificación CSS. Como resultado, un mejor rendimiento podría ser obtenido usando un selector CSS puro primero y después usando .filter(":header").

Por ejemplo, asume que hay un elemento article en una página web y tiene tres encabezados diferentes. Ahora, puedes usar $("article :header") en lugar de $("article h1, article h2, article h3") para brevedad. Para hacerlo incluso mejor, podrías usar $("article").filter(":header"). De esta manera tienes lo mejor de ambos mundos.

Para enumerar todos los elementos de encabezado, podrías usar el siguiente código.

1
$("article :header").each(function(index) {
2
  $(this).text((index + 1) + ": " + $(this).text());
3
  // Adds numbers to Headings

4
});

Prueba este demo de acompañamiento.

Ideas Finales

En este tutorial, discutí selectores poco comunes que podrías encontrar cuando usas jQuery. Mientras la mayoría de estos selectores tienen alternativas que puedes usar, aún es bueno saber que estos selectores existen.

Espero que hayas aprendido algo nuevo en este tutorial. Si tienes alguna pregunta o sugerencia, por favor comenta.