Modificar el documento con jQuery

De ChuWiki

Veamos cómo podemos añadir, reemplazar y eliminar elementos de nuestra página html usando jQuery.

Un documento de prueba[editar]

Antes de nada, hacemos un pequeño html para nuestras pruebas. Debemos añadir la librería jQuery entre <head> y </head>. En el ejemplo la cogemos directamente de la página de jQuery, pero podemos descargarla y ponerla en nuestro servidor. El html será este

<html>
   <head>
      <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
   </head>
   <body>
      <div>
         <p>primer párrafo</p>
         <p>segundo párrafo</p>
      </div>
   </body>
</html>

Hemos puesto un

con dos párrafos dentro, con los que jugaremos. Para ello, lo más fácil es guardar este fichero en un fichero html (por ejemplo, prueba.html) y abrirlo con google chrome. Este navegador viene con una consola de javascript que nos permitirá escribir y ejecutar el código javascript sobre la marcha, sin necesidad de editar, salvar y recargar la página html.

Una vez cargada en el navegador, con Ctrl + Mayús + J se abre la consola para poder escribir código javascript.


Añadiendo elementos al principio y al final[editar]

jQuery nos permite seleccionar los elementos de nuestro html de muchas formas, usando los selectores de CSS y otros mecanismos más complejos que jQuery aporta. Aquí sólo usaremos el selector css que coincide con el nombre del tag html, es decir, 'div', 'p', etc. Puedes usar nombres de clases CSS, identificadores, etc, etc.

Con los métodos append() y prepend() de jQuery podemos añadir más párrafos dentro del <div>, en la primera posición o en la última. Si ejecutamos

 $('div').append('<p>este va detras</p>');

se añadirá el párrafo como último elemento de todos los div, es decir, tendremos esto (sólo tenemos un div).

      <div>
         <p>primer párrafo</p>
         <p>segundo párrafo</p>
      <p>este va detras</p></div>

Si hacemos lo mismo con prepend(), se situará el primero de la lista

 $('div').prepend('<p>este va delante</p>');

y obtendremos

      <div><p>este va delante</p>
         <p>primer párrafo</p>
         <p>segundo párrafo</p>
      <p>este va detras</p></div>

Tenemos una variante de estos métodos que son appendTo() y prependTo(). Funcionan igual pero al revés, es decir, creamos el nuevo nodo html, llamamos a estos métodos en ese nuevo nodo y pasámos como parámetro el elemento html existente al que queremos añadir el nuevo nodo. El ejemplo anterior de append() podríamos haberlo hecho así

 $('<p>este va detras</p>').appendTo('div');

es decir, $('<p>este va detras</p>') crea el párrafo y lo añade (appendTo) al div existente.

Añadiendo hermanos[editar]

Los métodos after() y before() añaden el nuevo nodo detrás o delante del nodo seleccionado, como hermano. Si volvemos al html inicial y ejecutamos

 $('div').before('<p>parrafo delante de div</p>')

obtendremos el siguiente html

      <p>parrafo delante de div</p><div>
         <p>primer párrafo</p>
         <p>segundo párrafo</p>
      </div>

y si ahora ejecutamos el after

 $('div').after('<p>parrafo detras de div</p>')

obtendremos

      <p>parrafo delante de div</p><div>
         <p>primer párrafo</p>
         <p>segundo párrafo</p>
      </div><p>parrafo detras de div</p>

De igual forma, tenemos las variantes insertAfter() e insertBefore(), que se aplican al nuevo nodo para que sea añadido al que se pase como parámetro. Si ejecutamos

 $('<p>parrafo con insertAfter</p>').insertAfter('div')

el $('<p>parrafo con insertAfter</p>') crea el nuevo nodo y lo inserta detrás del div.


Reemplazar elementos[editar]

El método replaceWith() reemplaza un nodo (incluyendo todos sus hijos) por otro. Por ejemplo, para reemplazar el div del html original por un párrafo, podemos hacer esto

 $('div').replaceWith('<p>Un párrafo</p>');

y nos quedaría

<body>
   <p>Un párrafo</p>
</body>

De igual manera, tenemos un método alternativo que es replaceAll(). Si en el html original ejecutamos

$('<p>Un párrafo</p>').replaceAll('div')

obtenemos el mismo resultado.


Borrar elementos[editar]

Tenemos varias funciones que nos permiten eliminar elementos. empty() mantiene el elemento, pero borra todo su contenido. Si en el html inicial ejecutamos

  $('p').empty()

se borra el contenido de los párrafos, quedando

      <div>
         <p></p>
         <p></p>
      </div>

Si lo hacemos sobre el <div>, quedaría esto

 $('div').empty();

nos quedaría esto

 <div></div>

Para eliminar el elemento tenemos dos métodos, remove() y detach(). El método remove() es el que elimina definitivamente el elemento del documento. El método detach() elimina el elemento del documento, pero guarda los datos asociados a él y los manejadores de eventos que hayamos registrado. Este método detach() es útil si queremos eliminar el elemento temporalmente pero queremos restaurarlo más adelante con todo lo que tenía.

Si en el html inicial ejecutamos

   $('div').remove()

nos quedamos sin contenido entre los tags <body> y </body>

<head>
      <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
</head>
<body>
</body>

Con detach(), deberíamos guardarnos el elemento para poder restaurarlo luego. Por ejemplo, si ejecutamos la siguiente secuencia de órdenes

// Ponemos un manejador del evento click, haciendo que 
// muestre una ventana al hacer click en el primer párrafo
$('p:first').click(function(){alert ('hola')});  

// Eliminamos y nos guardamos el primer párrafo
var p = $('p:first').detach();

// Volvemos a añadir el primer párrafo. El click sigue funcionando.
undefined
$('div').prepend(p)

Si en el esa secuencia de órdenes usamos remove(), el click dejará de funcionar.

// Ponemos un manejador del evento click, haciendo que 
// muestre una ventana al hacer click en el primer párrafo
$('p:first').click(function(){alert ('hola')});  

// Eliminamos y nos guardamos el primer párrafo
var p = $('p:first').remove();

// Volvemos a añadir el primer párrafo. El click ya no funciona.
undefined
$('div').prepend(p)


Mover elementos[editar]

Podemos usar los métodos de añadir elementos pasando como parámetro un elemento ya existente en el documento. Esto hará que el elemento se elimine automáticamente de su posición y se situe en la nueva posición que le indiquemos. Por ejemplo, si en el html inicial ejecutamos

$('div').append($('p:first'))

el primer párrafo se desplazará detrás del segundo y nos dará

<div>
      <p>segundo párrafo</p>
      <p>primer párrafo</p>
</div>

Si el elemento tiene que añadirse en múltiples posiciones, se harán copias de él automáticamente. Si queremos que el elemento original se quede en su sitio, podemos hacer una copia de él llamando al método clone(). Si en el html inicial ejecutamos

$('div').append($('p:first').clone())

el $('p:first').clone() hará una copia del elemento original y la copia es la que será añadida, por lo que ahora tendremos dos párrafos iguales

<div>
     <p>primer párrafo</p>
     <p>segundo párrafo</p>
     <p>primer párrafo</p>
</div>


Añadir/eliminar padres[editar]

Con el método wrap() podemos añadir (insertar) un elemento padre en cualquier de los elementos. Por ejemplo, si en el html inicial ejecutamos

$('p:first').wrap('<div>')

el primer párrafo quedará rodeado de un <div> adicional

<div>
   <div><p>primer párrafo</p></div>
   <p>segundo párrafo</p>
</div>

Con unwrap(), podemos eliminar el padre inmediato. Eso afectará a todos los hermanos, que dejarán de tener padre. Por ejemplo, si en el html inicial ejecutamos

$('p:first').unwrap()

eliminaremos el <div> y nos quedarán los dos párrafos sueltos

<body>
    <p>primer párrafo</p>
    <p>segundo párrafo</p>
</body>

El método wrapInner() mete un nuevo elemento entre el padre y todos sus hijos. Si en el html inicial ejecutamos

$('div').wrapInner('<strong>')

Tendremos un <strong> entre el <div> y los párrafos, tal que así

      <div><strong>
         <p>primer párrafo</p>
         <p>segundo párrafo</p>
      </strong></div>

El método wrapAll() mete todos los nodos que le pasemos bajo un mismo padre, moviéndolos de sitio si es necesario. Por ejemplo, en el html inicial podemos ejecutar

$('p').wrapAll('<strong>')

para obtener lo mismo de antes

      <div><strong>
         <p>primer párrafo</p>
         <p>segundo párrafo</p>
      </strong></div>

pero si usamos un html como este

      <div>
         <p class="uno">primer párrafo</p>
         <p>segundo párrafo</p>
         <p class="uno">tercer párrafo</p>
      </div>

y ejecutamos lo mismo pero para la clase "uno" de esta forma

$('p.uno').wrapAll('<strong>')

obtendremos esto

      <div>
         <strong><p class="uno">primer párrafo</p><p class="uno">tercer párrafo</p></strong>
         <p>segundo párrafo</p>
      </div>

vemos que el tercer párrafo se ha puesto al lado del primero para poder tener un padre común <strong>

Múltiples elementos[editar]

Todos los métodos anteriores actúan sobre todos los elementos que encuentre el selector de jQuery. Es decir, si nuestro documento tuviera muchos div, el $('div') nos devolvería todos y el método que usemos en él (append(), prepend(), after(), before() o replaceWith()) actuaría sobre todos los div. Veamos, por ejemplo, qué pasa si ejecutamos en el html original esto

$('p').after('<hr/>')

esto añadirá una línea horizontal <hr/> detrás de cada párrafo

      <div>
         <p>primer párrafo</p><hr>
         <p>segundo párrafo</p><hr>
      </div>

También es posible algo un poco más complejo. Si a cualquiera de esos métodos le pasamos una función que devuelva un nodo html, se ira llamando a esa función para cada elemento que encuentre jquery y lo que devuelva la función será lo que se añada al html. Por ejemplo, si en el html original hacemos

$('p').before(function (indice) {
   return '<p> este es el parrafo'+indice+'</p>';
});

obtendremos el siguiente html de resultado

      <div>
         <p> este es el parrafo0</p><p>primer párrafo</p>
         <p> este es el parrafo1</p><p>segundo párrafo</p>
      </div>

La función que pasemos recibirá como parámetro el índice que indica el número de elemento en la lista, es decir, el primer párrafo encontrado es el 0, el segundo el 1 y así sucesivamente. Dentro de la función this corresponde con el elemento encontrado, es decir, la primera vez que jQuery llama a esta función, this será el objeto <p>primer párrafo</p>, la segunda vez el objeto <p>segundo párrafo</p>

Esto, por supuesto, no se puede hacer con los métodos inversos appendTo(), prependTo() ... ya que necesitan como parámetro un elemento al que añadir el html, no una función.