Actuálmente me encuentro maquetando una web en HTML5 y una de las funciones que debemos incorporar a la misma es la carga de módulos de HTML5 vía Ajax con jQuery.
Una vez incorporada la he probado como siempre en primer lugar en Firefox y todo perfecto. Como siempre después de firefox viene Internet Exploer y es en este punto donde empiezan los malos rollos . Al pinchar sobre uno de los enlaces del menú de navegación y realizarse la carga, los nuevos contenidos cargados han aparecido sin los estilos aplicados. El problema es que la librera Modernizr que utilizo para generar las nuevas etiquetas HTML5 solo se ejecuta la primera vez que cargamos la página por lo que todo el código que carguemos a posteriori vía Ajax no será reconocido por el navegador y por tanto saldrá sin los estilos asignados en la CSS.
Buscando un poco por Mr. Google he encontrado la librería innerShiv de tan solo 1kb aproximadamente que permite reconocer las nuevas etiquetas HTML5 añadidas al DOM ya sea vía JavaScript o Jquery.
Lo único que hay que hacer para que funcione es insertar la función innerShiv() dentro de la función que vayamos a utilizar para añadir el código ya sea de javascript o Jquery, con la única diferencia de que si utilizamos jquery tendremos que pasar un segundo parámetro a la función innerShiv, más concretamente una variable booleana false.
Os pongo dos ejemplos de como se utilizaría la función con javaScript y con jQuery
Las transiciones css nos permiten cambiar los valores de las propiedades de las hojas de estilo suavemente durante un intervalo de tiempo. Estas suaves animaciones peden ser provocadas por distintos eventos: click, hover, focus, active, o con cualquier cambio provocado sobre el elemento.
Actualmente para conseguir animar un botón cuando recibe uno de estos eventos necesitamos hacer uso de algún sprite o de código javaScript si el efecto que le queremos dar a la transición es más específico. Mediante las transiciones CSS, con tan solo unas pocas líneas de código conseguiremos animar nuestros botones en poco tiempo y con efectos muy conseguidos.
Nos vamos a encontrar con tres partes de la transición en la declaración:
transition-property: La propiedad sobre la que se va a realizar la transición
transition-duration: Duración de la transición (ms-milisegundos, s-segundos)
transition-timing-function: Como de rápido se da la transición. Puede tomar los siguientes valores:
ease
linear
ease-in
ease-out
ease-in-out
cubic-bezier
Retrasando la transición
Existe la posibilidad de retrasar la animación durante un intervalo de tiempo. Este efecto lo conseguiremos con el uso de transition-delay
Prefijos y metodo abreviado
Para que las transiciones funcionen correctamente en los navegadores que las soportan tendremos que utilizar los respectivos prefijos que utilizan cada una para hacer las declaraciones, así por ejemplo para el ejemplo que haré a continuación haré 4 declaraciones.
Una de las ventajas más esperadas de CSS3 es la posibilidad de insertar varios fondos en un mismo elemento, esto nos permitirá que nuestro HTML sea mucho más simple y evitaremos problemas de divitis.
Como siempre voy a realizar un ejemplo muy sencillo y vamos viendo como utilizarlo. Me he descargado una serie de imágenes que representan distintos estados meteorológicos (nubes, sol y nubes, lluvia y un arco iris) y vamos a intentar plasmarlas todas ellas sobre un mismo contenedor.
Como podéis ver hemos creado un solo contenedor sin tener que recurrir a una estructura del tipo:
<div id="fondo1">
<div id="fondo2">
</div>
</div>
Cuanto antes declaremos un fondo menor z-index tendrá este. Según he colocado yo mis fondos el arco iris será el elemento que tendrá más profundidad, a continuación las nubes, seguido de la lluvia y por último el sol.
Esta vez voy a intentar explicar como realizaríamos una carga ajax de un archivo xml el cual contiene cierta información que queremos mostrar en nuestra web, para ello realizaré un ejemplo y os iré describiendo detalladamente todos los pasos que voy siguiendo. En nuestro ejemplo tendremos un listado con tres películas, al pinchar sobre cada una de ellas conectaremos con un archivo xml que es donde gurdamos toda la información relativa a las tres pelis, buscaremos la información relativa a la película sobre la que se a clicado y la imprimiremos por pantalla en un formato HTML específico. A continuación os pongo el ejemplo en funcionamiento:
El primer paso que daremos será asignar el evento correspondiente a cada uno de los enlaces disponibles en el listado, en nuestro caso son tres.
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
}
else {
window.onload = function() {
oldonload();
func();
}
}
}
function anadeEvento(elemento,evento,funcion) {
if(document.addEventListener){
elemento.addEventListener(evento, funcion, false); // Resto navegadores
}
else{
elemento.attachEvent("on"+evento, funcion ); // IE8-
}
}
//Asignamos eventos
addLoadEvent(function() {
var listado_pelicula = document.getElementById("listado-peliculas");
var enlaces_pelicula = listado_pelicula.getElementsByTagName("a");
for(var i=0; i<enlaces_pelicula.length; i++)
anadeEvento(enlaces_pelicula[i], "click", function(e){cargadorPeliculas(this.getAttribute("id")); e.preventDefault();});
});
Para evitar el uso de javascript intrusivo hacemos uso de las funciones addLoadEvent y anadeEvento (ya hable de estas funciones en este post)
Una vez se haya cargado la página capturamos los tres enlaces del listado y los recorremos uno por uno pasándolos como parámetro a la función anadeEvento, junto con el evento que deseamos, en este caso el evento click y junto a la función que queremos que se ejecute al hacer clic sobre uno de nuestros enlaces.
Mucho cuidado con llamar a la función que queremos ejecutar directamente, porque no nos funcionará. Por ejemplo:
Podríamos conseguir lo mismo con jquery de la siguiente forma:
$("div").attr("id", "mi_id");
textContent Vs innerText
Estos dos métodos nos permiten conseguir lo mismo, obtener el texto englobado por un elemento en concreto con la diferencia de que cada uno funcionará o no dependiendo del navegador en el que se ejecuten. Así por ejemplo textContent funcionará en Firefox pero no en IE. Por el contrario innerText trabajará correctamente en IE ero no en firefox. Una forma válida de conseguir nuestro propósito con éxito en todos los navegadores sería la siguiente:
Una forma más sencilla de obtener el texto de un elemento sin tener que recurrir a condicionales con los cuales diferenciar entre navegadores sería mediante el método innerHTML. Mediante este método recuperaremos tanto el texto como el etiquetado HTML englobado por un elemento en concreto.
Ejemplo: (Imaginemos que queremos fijar un texto en un contenedor cuyo id es "mi_id"):
document.getElementById('mi_id').innerHTML = "<p>Nuevo texto insertado en mi_id</p>";
Debido al distinto comportamiento de los navegadores web muchas veces se hace imprescindible detectar el nombre del mismo así como la versión que se está utilizando para realizar una programación determinada.
Gracias al objeto navigator de javaScript podemos detectar tanto el nombre como la versión de navegador que se está utilizando. El objeto navigator tiene varias propiedades aunque quizás la más interesante sea userAgent. Mediante el uso de expresiones regulares aplicadas sobre esta propiedad podremos detectar la información que necesitamos.
Tenéis información detallada sobre el objeto navigator en la siguiente dirección:
Navegando un poco por la red me he topado con algunas funciones de javaScript bastante interesantes y que considero necesario tenerlas bien a mano por lo que las guardo en este post por si hay que rescatarlas.
toggle()
Ocultará o mostrara elementos dependiendo del estado anterior.
function toggle(obj) {
var el = document.getElementById(obj);
if ( el.style.display != 'none' ) {
el.style.display = 'none';
}
else {
el.style.display = '';
}
}
A la hora de manipular el DOM tenemos el siguiente listado de expresiones
document.getElementById(id_elemento);: Permite acceder al primer elemento con id “id_elemento”
document.getElementsByTagName(elemento): Devuelve una lista de nodos con todos los elementos con el nombre “elemento”. En caso de querer hacer referencia a un elemento específico, por ejemplo el primero, podríamos hacer uso de la expresión: document.getElementsByTagName(elemento)[0]
document.createElement(elemento);: Crea un nuevo elemento en el DOM
document.createTextNode(“texto”);: Genera un nuevo nodo de texto.
appendChild: Añade un nodo hijo a un padre concreto. Por ejemplo:
var nuevoEnlace = document.createElement("a");
var nodoTexto = document.createTextNode("Esto es un enlace");
nuevoEnlace.appendChild(nodoTexto);
elementoPadre.insertBefore(nuevoElemento, elementoReferenciado);: Inserta un elemento justo antes de otro que le especifiquemos.
innerHTML: Permite introducir HTML dentro de una etiqueta.
parentNode: Selecciona el nodo padre de un nodo en concreto.
removeChild: Elimina un nodo hijo
getAttribute(propiedad);: Devuelve el valor de una propiedad que le pasamos por parametro
ancla.style.display: Devuelve un estilo concreto de un elemento
document.getElementsByClassName(names);: Retorna un conjunto de elementos los cuales poseen la clase “names”.
getElementsByClassName pertenece a la nueva especificación de HTML5 y tan solo algunos navegadores lo soportan, por ejemplo Internet Explorer en todas sus versiones inferiores a la 9.
Hasta que todos los navegadores soporten getElementsByClassName podremos hacer uso de la siguiente función:
function getElementsByClass(searchClass,node,tag) {
var classElements = new Array();
if ( node == null )
node = document;
if ( tag == null )
tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)');
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}