Entradas de agosto 11UTC 2009 en Dave Ruiz Blog

En ocasiones, ocurre que el evento onLoad, por ejemplo, de una imagen no es lanzado a la hora de cargar una página.

Imaginemos que en el script de una página, una vez cargado el DOM, añadimos una función determinada cuando carga la imagen de cabecera:

<script type="text/javascript">
  // Función que ejecutamos al cargar el DOM de la página
  window.onload = function() {
    var cabecera = document.getElementById("cabecera");
    // Funcion lanzada cuando carga la imagen 'cabecera'
    cabecera.onload = function() {
      alert("carga completa");
   ;}
  }
</script>

Nos encontraremos con que en algún navegador (por ejemplo, Internet Explorer) lanza la primera vez el evento, pero en las posteriores cargas este no es lanzado.

La razón es que, en la segunda carga, la imagen se encuentra cacheada y por tanto el navegador carga la imagen en cuanto inserta el elemento IMG, lanzando el correspondiente evento onLoad. Como en ese preciso momento todavía estamos cargando la estructura de la página y el evento no ha sido asignado (no se asigna hasta la carga completa de la estructura), cuando queremos asignarlo ya es demasiado tarde.

Otros navegadores como Mozilla Firefox no lanzan los eventos hasta que se ha completado la carga del DOM, haciendo inexistente este problema.

Una solución sencilla es comprobar, después de asignar el evento onLoad a la imagen, si esta ya se encuentra cargada complétamente. Nos serviremos del parámetro complete. Si nos devuelve true, lanzamos el evento onLoad manualmente.

<script type="text/javascript">
  // Función que ejecutamos al cargar el DOM de la página
  window.onload = function() {
    var cabecera = document.getElementById("cabecera");
    // Funcion lanzada cuando carga la imagen 'cabecera'
    cabecera.onload = function() {
      alert("carga completa");
    }
    if (cabecera.complete == true) cabecera.onload();
  }
</script>

Actualización:

Me comenta Marc Palau (y con toda la razón) que el ejemplo anterior no es válido porque onLoad no es lanzado hasta que carga toda la página, incluidas las imágenes. En este caso, nunca seran llamados los eventos onLoad de las imágenes porque se están definiendo después de haberlas cargado.

Para reproducir el error, he preparado una prueba en la que se testea el framework jQuery y la función addDOMLoadEvent (el ejemplo que ponen en el enlace añade la imagen dinámicamente y no lo reproduce). Del mismo modo, se presenta una solución para ambas basados en el mismo procedimiento comentado antes.