Scriptia. Javascript y buenas prácticas en español



Scriptia / Etiquetas /

Saltar a Acerca de Scriptia

Estás viendo la página para la etiqueta (o conjunto de etiquetas) .

Etiquetas relacionadas: +|, + |, + |

Ajax, eventos y jQuery

Un «problema» con el que todo novato de la programación con jQuery se encuentra tarde o temprano (y las listas de correo lo demuestran) es que el contenido cargado (o generado) dinámicamente no dispara los manejadores de eventos asignados en $(document).ready.

Y, hoygan, esto es de lo más normal.

Si repasamos nuestra forma habitual de trabajar con jQuery, y reflexionamos un poquito…

$(document).ready(function() {
  $('selecciono.algo')
    .bind('click', hazCosasBonitas);
});

… recordaremos que estamos utilizando $(document).ready porque no podemos seleccionar elementos que no existen. De ahí que tengamos que esperar a disponer de un árbol DOM completo. De ahí que los manejadores de eventos no afecten a elementos nuevos.

¿Entonces?

Opciones las hay adecuadas a unos casos y a otros. La más sencilla, para casos sencillos, es inicializar los contenidos nuevos una vez los hayamos insertado en el documento.

Necesitamos, pues, una función que nos permita seleccionar y actuar dentro de un contexto. Recuerda que jQuery provee de selecciones basadas en contexto. Si utilizas

$('a');

seleccionarás todos los enlaces del documento. Pero si usas

$('a', unElementoSelecto);

seleccionarás los enlaces descendientes de unElementoSelecto.

Por tanto, podemos crear nuestra función de inicialización según contexto como sigue.

function initLinks(context) {
  $('a', context)
    .bind('click', hazCosasBonitas)
}

Que ejecutaremos desde nuestro manejador para $(document).ready, pasando el documento como contexto de búsqueda:

$(document).ready(function() {
  initLinks(document);
});

Así que estamos como al principio… pero mucho más cerca del final. Lo único que nos queda por hacer es ejecutar initLinks cuando recuperemos nuevo contenido. Si usamos load, el más simplón de los métodos Ajax de jQuery, basta con usar una función de callback:

function loadNewContent() {
  $('#holder').load('ajax-content.html #response p', function() {
    // `this` apunta al elemento que acabamos de rellenar
    initLinks(this);
  });  
}

Y esta es la idea básica, que he reflejado en esta pequeña demo en latín.

Por supuesto, hay otras opciones. Si eres de los que para clavar un clavo usa un plugin, échale un vistazo a LiveQuery; si tienes un serio trasiego de elementos vivos, mejor apostar por la delegación de eventos. Pero esas son otras historias que contaré a su debido momento.

Inicialización inmediata de scripts externos

Uno de los problemas del javascript no intrusivo es la inicialización. Si el documento (o la interfaz) incluye imágenes, window.onload se dispara demasiado tarde y el usuario se enfrenta a controles que no responden. Dean Edwards nos da buenas nuevas en window.onload (again). Esta solución ya se ha incorporado a la versión SVN de jQuery.

Acerca de Scriptia

Saltar a la caja de búsqueda

Scriptia forma parte del PDM de Choan C. Gálvez, desarrollador web residente en Barcelona. Scriptia pretende mejorar la calidad de la documentación acerca de javascript disponible en español.