En la entrada anterior, vimos los objetos básicos en javascript. Ahora vamos a ver cómo usarlos para seleccionar elementos.

Hay actualmente muchos métodos para seleccionar elementos del DOM (básicamente la estructura de una página web). Por desgracia, si se quiere seleccionarlos efectivamente en diferentes navegadores, no están todos disponibles (esto es lo que pasa cuando los navegadores antiguos , como IE 7-8, no dejan de ser utilizados). Vamos a darles un repaso a todos:

document.getElementById

Éste es más seguro de utilizar, junto con getElementsByTagName. Como su nombre indica, sirve para seleccionar un elemento por su ID. ¿Y qué es el id? Cuando escribimos una etiqueta HTML podemos configurar su atributo id. Así, si probáis en la consola (ver la entrada anterior) document.getElementById('parrafo-ejemplo') (cuidado con las letras mayúsculas), deberíais de obtener éste mismo párrafo. ¿Por qué? Porque este texto está escrito entre <p id='parrafo-ejemplo'> y </p>.

Nota: Éste método es el único que requiere llevar document al principio. El resto pueden llevar o bien document, o bien un contexto. Un contexto es un elemento previamente seleccionado. Sólo en ese elemento se seleccionará lo indicado (veremos un ejemplo abajo). Si usamos document buscaremos en toda la página actual.

document.getElementsByTagName

Éste elemento selecciona todos los elementos que tengan una determinada etiqueta (div, a, p...) dentro del contexto. Al seleccionar varios elementos, nos tiene que devolver una array bueno, no exactamente, nos devuelve una colección de elementos, pero la forma de acceder es la misma, así que ya deberíamos saber. La etiqueta * es un comodín, así que devuelve todas las etiquetas (o sea, todos los elementos).

Vamos a ver un ejemplo con contexto:


//Con la coma declaramos varias variables
//El párrafo será el contexto
var elParrafo = document.getElementById('parrafo-ejemplo'),
//Los códigos será la lista de elementos con la etiqueta <code> dentro de ese párrafo
losCodigos = elParrafo.getElementsByTagName('code');
//Seleccionamos el primer elemento, y mostramos por pantalla su contenido (innerHTML, que no tenéis por qué saberlo)
alert(losCodigos[0].innerHTML)

Por pantalla debería de salir “getElementsByTagName”, que es el contenido del primer código del párrafo.

getElementsByClassName

El uso es similar a getElementsByTagName, sólo que en vez de devolver elementos según una etiqueta, los devuelve según la clase del elemento. Por ejemplo, vete a la página principal y usa document.getElementsByClassName('postCon'). Seleccionarás todos los contenedores que uso para los posts.

Éste método está disponible en todos los navegadores excepto IE < 9. Para ver tablas completas ve aquí.

querySelector y querySelectorAll

Éstos métodos son los más intuitivos y fáciles de usar pero, al igual que getElementsByClassName, no están disponibles en IE menor a 9 no está disponible en IE7 (aunque ahora mismo no lo considero un inconveniente para usarlo) (tampoco está en firefox 3, pero es una versión no utilizada en absoluto). Estos métodos usan cadenas similares a las de CSS para seleccionar elementos. querySelector sólo selecciona el primer elemento encontrado, mientras que querySelectorAll selecciona todos. Por ese mismo motivo, uno devuelve el elemento en sí y otro una colección. Veamos un ejemplo:


//El primer párrafo del post
var primerParrafo = document.querySelector('.post-body p'),
//Recordad que el 0 es el primero
segundo = document.querySelectorAll('.post-body p')[1],
elTextoDeAmbosJuntos = primerParrafo.innerHTML + segundo.innerHTML;
//Para escribirlo
document.querySelector('#parrafo-vacio').innerHTML = elTextoDeAmbosJuntos;

Ahora deberíais de ver el texto de ambos juntos en el párrafo superior a este. Para volver a vaciar el párrafo podéis usar document.querySelector('#parrafo-vacio').innerHTML = ""

Seleccionar un elemento desde otro

Supón que quiero seleccionar este post, pero no tengo forma segura de hacerlo (salvo darle una ID). Sin embargo, sabemos que hay un párrafo con la id párrafo vacío que es hijo de este post. ¿Cómo seleccionarlo a partir de ese párrafo?

Cada elemento tiene ciertas propiedades que nos permiten acceder a otros elementos. Algunas de las más conocidas y seguras son parentNode, previousSibling y nextSibling, que seleccionan el elemento padre, el anterior y el siguiente (estos dos últimos pueden seleccionar nodos de texto, así que cuidado). Igualmente para seleccionar hijos tenemos children y childNodes (sobre los que profundizaremos más adelante). Así que para seleccionar el post tendríamos que hacer:


var elParrafo = document.getElementById('parrafo-ejemplo'),
elPost = elParrafo.parentNode;
//Mostramos la clase del post (sólo para asegurarse de que funciona)
alert(elPost.className)

Conclusión

Espero que os sea útil esta información. Para acabar, me gustaría que pensarais sobre una frase que escribí en la entrada anterior: En javascript todo es un objeto. Fijaos en la forma de acceder a las funciones propias del documento. ¿ O acaso document.getElementById no es similar a persona.mostrarNombre? ¿No es lo mismo acceder al padre de un elemento usando elemento.parentNode que acceder a la altura de una persona usando persona.altura, o usar document.getElementsByTagName y "miString".split?

Espero que esta pequeña reflexión os ayude a verlo todo con otros ojos, para que podáis ver que realmente en javascript podemos editarlo todo.
P.D.: Ahora que ya sabemos seleccionar elementos, el próximo paso será editarlos, ¿no?

10 pensamientos en “Básicos de javascript[2]: Seleccionando elementos

  1. Imagen de Abraham Santos Fernández el dijo:

    Emilio, por razones ajenas a mi voluntad tengo que poner privado a Músicos Unidos. Quisiera que puedas ver la página para que sigas viendo las entradas que voy a seguir publicando. Solamente deja tu E-mail aquí o envíamelo al correo siguiente: as75534@gmail.com.

    Y enviarte la invitación para que puedas ver mi blog. ¡Saludos!

  2. getAttribute y setAttribute en Javascript | Emilio Cobos-CMC
  3. Imagen de Marcos el dijo:

    Excelente aporte!. Tengo una pregunta: Tengo varios

  4. con la misma clase (Class=”image”) y sin id. pero sólo quiero seleccionar y contar los que tienen la propiedad style=”display: none”. Cómo puedo filtrar mi selección inicial de todos los Class=”image”, en sólamente los que tengan ésta propiedad style?

    Saludos!

    • Imagen de Emilio Cobos Álvarez el dijo:

      Vale, puedes hacer varias cosas… Si necesitas recorrerlas más de una vez necesitas eliminar las que no te interesan. Para ello convertiremos en una array el NodeList con Array.prototype.slice, y usaremos Array.prototype.filter (es de ES5, pero se puede hacer un polifyll para navegadores más antiguos):

      var hiddenImages = [].slice.call(document.querySelectorAll('.image')).filter(function(image) {
          return image.style.display === "none";
      });

      Si sólo necesitas iterarlas una vez puedes hacer algo como esto:

      [].slice.call(document.querySelectorAll('.image')).forEach(function(image) {
          if ( image.style.display !== "none" ) {
              return;
          }
      
          // Hacer algo con la imagen
      });

      O si necesitas mucho rendimiento el equivalente con el loop for:

      (function() {
          var images = document.querySelectorAll('.image'),
              len = images.length,
              i,
              image;
      
          for ( i = 0; i < len; i++ ) {
              image = images[i]:
              if ( image.style.display !== "none" ) {
                  continue;
              }
              // Hacer algo con la imagen
          }
      }());
  5. Imagen de PabloPablo el dijo:

    Hola, gran artículo pero me ha surgido una duda.

    Quiero añadir un texto a todos los elementos ‘p’ del documento, selecciono todos ellos con un getElementsByTagName(‘p’) y después corro un ciclo for para ir añadiendo uno a uno el nuevo texto.
    El problema es que la consola de Chrome me da un error con el innerHTML:
    Uncaught TypeError: Cannot read property ‘innerHTML’ of undefined

    El codígo en cuestión es el siguiente:
    https://jsfiddle.net/d054vftc/

    ¿Qué es lo que estoy haciendo mal?
    ¿Existen otros métodos más adecuados para añadir nodos de texto a elementos?

    Muchísimas gracias

  6. Imagen de RodriRodri el dijo:

    Hola.
    Y si necesito listar todos los elementos que tengan una clase pero no otra?

    Muchas gracias. Saludos.

    Siendo las clases P0,P1, C, y hide respectivamente.

    Quiero saber como podria devolverme la clase P0 que es la que tiene el div con las clase C y Hide.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Puedes usar las siguientes etiquetas y atributos HTML:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre data-language=""> <ul> <ol> <li>
Para poner código usa <pre data-language="[lenguaje]"><code>[código]</code></pre>, y no olvides escapar el HTMl.