Cómo solucionar el error de window.onload

Esta tarde, revisando los blogs de mis amigos me topé con un post de Oscar Godson, en el cual aporta una solución al ya famoso “Internet Explorer no puede abrir el sitio. Operación anulada” que tan malos momentos me hizo pasar alguna vez.

La solución de Oscar, consiste en usar jQuery para solucionar el bug con una sencilla función:

$(window).load(function(){
//Acá tu código
});

De verdad sencilla y conveniente si ya estás usando jQuery en el proyecto, pero qué pasa si no? Ahí es donde cobra sentido este post. No nos conviene cargar 30k de código extra para poder resolver este problema solamente, sería matar una mosca con un cañón.

Hace poco más de un año dí con una solución, eficiente, agnóstica y que responde bien en todos los browsers… Para ie a veces basta con agregar defer cómo atributo.

<script defer src="ie_load.js" type="text/javascript"></script>

Y el contenido del ie_load.js sería el script que ie debe cargar cuando esté listo. Suena bien, pero es una solución que no funciona adecuadamente con los otros browsers que simplemente ignorarían el defer, Mozilla y Safari quedarían rezagados.

Afortunadamente Mozilla responde a su propio DOMContentLoaded entonces solo queda escuchar el evento y ejecutar lo que queramos con él:

document.addEventListener("DOMContentLoaded", init, false);

Y John Resig, el creador de jQuery, dió con la solución para safari hace un tiempo:

if (/WebKit/i.test(navigator.userAgent)) { // sniff
		var _timer = setInterval(function() {
			if (/loaded|complete/.test(document.readyState)) {
				init(); // call the onload handler
			}
		}, 10);
	}

Para los demás browsers, solo nos queda hacer uso del window.onload común y corriente que todos conocemos:

window.onload = init;

Ya teniendo todos estos ingredientes dispuestos, solo queda hacerlos funcionar en conjunto, haciendo uso del soporte para compilaciones condicionales que tiene ie (para que no se meta con lo demás) y uno que otro tweak, ponemos todo en un solo script que se encargue del onload adecuado para cada browser.

function init() {
 		if (arguments.callee.done) return;

 		arguments.callee.done = true;

 		if (_timer) {
			clearInterval(_timer);
			_timer = null;
		}

		// Acá va lo que queramos ejecutar

	};

	/* Para Mozilla */
	if (document.addEventListener) {
		document.addEventListener("DOMContentLoaded", init, false);
	}

	/* Para Internet Explorer */
	/*@cc_on @*/
	/*@if (@_win32)
		document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
		var script = document.getElementById("__ie_onload");
		script.onreadystatechange = function() {
			if (this.readyState == "complete") {
				init(); // call the onload handler
			}
		};
	/*@end @*/

	/* Solución de John Resig Para Safari */
	if (/WebKit/i.test(navigator.userAgent)) { // sniff
		var _timer = setInterval(function() {
			if (/loaded|complete/.test(document.readyState)) {
				init(); // call the onload handler
			}
		}, 10);
	}
	window.onload = init;

Recuerdo que esta solución me ayudó bastante, en especial con SwfObject, así que espero que a alguien más le sirva de algo.

  • The defer method didn't work for me. That's why I used my method, the $(window).load one, but I didn't know there was a way with Safari! Nice! Will use in the future thanks.
  • Anytime bro ;).

    Actually your $(window).load is a cool and neat method if you're already using jQuery.
blog comments powered by Disqus
  • Mail
  • Delicious
  • Digg
  • StumbleUpon
  • Twitter
  • Technorati