Mostrando la categoría Programación.

Os dejo una pequeña y sencilla función para realizar esta tarea en Javascript. Evidentemente, está sujeto a las mejoras que creáis convenientes.

function XMLString( object, name, recursiveCall ) {
	var xml = "", i;
	var isArray = typeof(object) === 'object' && typeof(object.length) === 'number' &&  !(object.propertyIsEnumerable('length')) && typeof(object.splice === 'function');

	if (!recursiveCall)	{
		xml += "<?xml version=\"1.0\" ?>";;
		xml += "<"+name+" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
	} else if (!isArray) {
		xml += "<"+name+">";
	}

	if (typeof(object) === "undefined" || object == null) return ""; //Nada
	else if (typeof(object) === "object") for (i in object) xml += XMLString( object[i], isArray?name:i, true); // Un objeto o array
	else xml += object; // Un texto

	if (!isArray || !recursiveCall) xml += "</"+name+">";

	return xml;
}

Y un ejemplo de uso sería:

var objeto = {
	campo1 : "valor1",
	campo2 : "valor2",
	campo3 : "valor3"
}

alert( XMLString( objeto, "XML" ) );

Donde el primer parámetro es el objeto a convertir, y el segundo es el nombre del elemento raíz. Con el ejemplo anterior obtendríamos como salida la siguiente cadena:

<?xml version="1.0" ?>
<XML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <campo1>valor1</campo1>
    <campo2>valor2</campo2>
    <campo3>valor3</campo3>
</XML>"

Con 4 cambios es posible convertirlo en código AS2 o AS3. Aunque en estos casos creo que hay métodos mejores y nativos para hacer esta función.

De todos es conocido el problema de emplear la pseudo-clase :hover con Internet Explorer 6. Este funciona solamente con los hipervínculos (<a></a>) dejando fuera al resto de elementos.

Con la ayuda de jQuery, podemos solventar de manera fácil este problema añadiendo unas lineas al inicio del script, y teniendo en cuenta una regla en el CSS que contenga los estilos.

Por ejemplo, teniendo el siguiente CSS:
#menu li:hover {
text-decoration:underline:
}

Habría que modificarlo tal que:
#menu li:hover, #menu li.hover {
text-decoration:underline:
}

De manera que podamos acceder a dicho estilo mediante una clase.

Y ahora, solo quedaría realizar un script que añada la clase o la elimine según el evento llamado. Para ello emplearemos la función hover(mouseOver, mouseOut) que nos facilita jQuery.
$(document).ready( function() {
if ($.browser.msie) $("*").hover( function() { $(this).addClass("hover"); }, function() { $(this).removeClass("hover"); } );
});

Y a funcionar :D

Por alguna razón, Adobe no implementó un método para detener la descarga de un archivo FLV cuando queremos eliminar un componente FLVPlayback. Puedes crear un reproductor FLV dinámicamente y luego destruirlo, pero si ha comenzado la reproducción el fichero FLV continuará descargándose hasta que termine.

La clase FLVPlayback implementa el método closeVideoPlayer( índice ) que permite detener la descarga del archivo FLV que esté descargando, pero está limitado a cuando abres múltiples vídeos en un solo componente. La limitación consiste en no dejarte eliminar el la conexión de video con la que creaste el reproductor.

// Creamos el reproductor y lo ponemos a reproducir
var video:FlvPlayback = new FlvPlayback();
video.play( "video.flv" );

// Ahora intentamos cerrar el reproductor
video.stop();
video.closeVideoPlayer(0); // Debería detener la descarga, pero nos lanza un error
video = null; // Para que el Garbage Collector lo elimine de memoria

Si en el ejemplo omitimos video.closeVideoPlayer(0), el reproductor se elimina, pero el vídeo continúa descargándose y consumiendo ancho de banda.

Esto puede ser un problema cuando haces uso de varias instancias de este componente, y debido a las circunstancias no puedes usar uno solo. Cada una de ellas llamará a la descarga de un FLV, y puede darse el caso de estar descargando varios FLV a la vez, con el consiguiente consumo de ancho de banda.

La solución, acceder a la primera instancia VideoPlayer y detenerlo uno mismo:

// Ahora intentamos cerrar el reproductor
video.stop();
video.getVideoPlayer(0).close(); // Ahora sí, detiene la descarga del archivo FLV
video = null; // Para que el Garbage Collector lo elimine de memoria

Algo muy sencillo, pero que ya me ha hecho perder algo de tiempo buscándolo :P .  Aquí lo dejo como apunte.

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.

A modo de apunte, os dejo un método breve, usando jQuery, para resaltar los enlaces que apuntan a la página en la que nos encontramos. Muy útil, por ejemplo, para destacar en los menús la opción seleccionada automáticamente sin recurrir a PHP o a hacerlo manualmente:

$(document).ready( function() {

var loc = document.location.href.split(/[\?#]/).shift().replace(/\/$/, ”);

$(“a”).each(function() {

if (this.href == loc) $(this).addClass(“selected“);

});

} );

El funcionamiento es muy simple. Recorre todos los elementos <a> de la página y compara el parámetro href con la url actual. Si coincide, añade la clase ‘selected‘ a dicho elemento. La clase ’selected’ deberá estar definida dentro de los estilos css de la página.

Un ejemplo aquí.

Actualización: Ahora no tiene en cuenta si la URL tiene barra al final o no (como en el caso de las carpetas)

Una precarga (muy) sencilla para Flash (AS3).  Suponiendo que el primer fotograma está vacío, podemos incluir el siguiente código en la linea de tiempo principal:

stop(); root.loaderInfo.addEventListener(Event.COMPLETE, function(e:Event) { play(); });

Esto comenzará a reproducir el flash en cuanto termine de cargar. Además, podemos aprovechar el primer fotograma para poner un mensaje ‘cargando… ‘, que será lo que se muestre mientras se completa la carga.