UNIVERSIDAD DON BOSCO FACULTAD DE ESTUDIOS TECNOLÓGICOS COMPUTACIÓN Nombre de la Practica: CICLO: 02/2014 Lugar de Ejecución: Tiempo Estimado: MATERIA: DOCENTES: GUÍA DE LABORATORIO #11 JSON, localStorage y sessionStorage Centro de Cómputo 2 horas con 30 minutos Lenguajes Interpretados en el Cliente Inga. Karens Lorena Medrano / Ing. Ricardo Ernesto Elías I. OBJETIVOS Que el estudiante: Adquiera dominio en la utilización de los principales métodos que ofrece JavaScript para trabajar con objetos JSON. Comprenda las opciones para trabajar con almacenamiento local tanto con localStorage como con sessionStorage entendiendo sus diferencias. Utilize las propiedades y métodos para el trabajo con los objetos localStorage y sessionStorage. II. INTRODUCCIÓN TEÓRICA JSON (Notación de objetos de JavaScript) JSON es una manera más simple de representar objetos de JavaScript como cadenas, es una alternativa más simple a XML para pasar datos entre el cliente y el servidor. En JSON, cada objeto se representa como una lista de nombres de propiedad y valores contenidos entre llaves, en el siguiente formato: {“NombrePropiedad”:valo1,”NombrePropiedad2”:valor2} Los arreglos en json se representan en JSON mediante corchetes en el siguiente formato: [valor1,valor2,valor3] Cada valor puede ser una cadena, un número, una representación de JSON de un objeto, true, false o null. Podemos convertir cadenas JSON en objetos de javascript mediante la función JSON.parse de JavaScript. Las cadenas JSON son más fáciles de crear y analizar que XML, además de que requieren menos bytes. Por estas razones. JSON se utiliza con frecuencia para comunicarse en la interacción cliente-servidor. Métodos para trabajar con JSON Para trabajar más fácilmente con objetos JSON y un lenguaje de programación como JavaScript se utilizan dos métodos nativos que facilitan la utilización de estos objetos para distintos propósitos: JSON.parse(): Este método analiza una cada de texto y la transforma en un objeto JSON a partir de pares property:value; contenidos en la cadena. JSON.parse(cadena[, transformador] ); La cadena son transformados de acuerdo a lo establecido en esta función antes de ser asignados como valores del objeto JSON. El transformador retorne undefined al intentar transformar el valor de una propiedad, dicha propiedad será eliminada del objeto. JSON.stringify(): Este método recibe un objeto JavaScript y devuelve su JSON equivalente y puede tomas hasta tres parámetros. JSON.stringify(objeto[, reemplazador[, separador]]); El método JSON.stringify() recibe un objeto JavaScript como primer argumento y devuelve su JSON equivalente. El primer argumento es el único obligatorio y en la práctica es un objeto o matriz (arreglo), aunque también puede ser una cadena, booleano, número o valor nulo. El parámetro opcional reemplazador, es una función que modifica la forma en que los objetos y los arreglos se encadenan. El parámetro opcional separador, es una cadena o número usado para insertar caracteres o espacios en blanco en la cadena de texto JSON, permitiendo una mejor legibilidad. localStorage A partir de HTML5 hay dos nuevos mecanismos para almacenar pares claves/valor que ayudan a eliminar algunos problemas con las cookies. Las aplicaciones Web pueden usar la propiedad localStorage del objeto Windows para almacenar hasta varios megabytes de datos de cadena de pares clave/valor en la computadora del usuario y pueden acceder a esos datos entre sesiones de navegación y pestañas del navegador. A diferencia de las cookies, los datos en el objeto localStorage no se envían al servidor Web con cada solicitud. El dominio de cada sitio Web tiene un objeto localStorage separado: todas las páginas de un dominio dado comparten un objeto localStorage. Por lo general se reservan 5MB para cada objeto localStorage, pero un navegador Web puede preguntar al usuario si debe asignar más espacio cuando este llene. sesionStorage Las aplicaciones Web necesitan acceso a los datos solo para una sesión de navegación y que deben mantener esos datos separado entre múltiples pestañas pueden usar la propiedad sesionStorage del objeto Windows. Hay un objeto sesionStorage separado por cada sesión de navegación, incluyendo pestañas separadas que accedan al mismo sitio Web. Otros métodos y propiedades Propiedad length La propiedad length permite saber el número de datos (pares "clave/valor") que tenemos almacenados. su sintaxis es: num = localStorage.length; La variable num nos dice el número de datos que tenemos guardados. Borrar datos Los datos mientras no les digamos otra cosa se almacenan de forma permanente y sin fecha de caducidad, por lo que si queremos borrar algún dato debemos hacerlo de forma manual, utilizando el método removeItem() de la siguiente manera: localStorage.removeItem("clave"); En el ejemplo anterior para borrar el dato haremos lo siguiente: localStorage.removeItem("nombre") Debemos pasar como argumento la clave del elemento que queremos borrar. Si la "clave" que pasamos en el argumento no existe el método simplemente no hará nada. Método key() El método key() nos permite saber las claves que tenemos guardadas. Las claves se guardan en un array, por lo que como argumento pondremos el número de elemento de la clave. clave = localStorage.key(0); Este ejemplo nos devuelve la clave del primer elemento guardado. Aunque este método no es muy útil para buscar claves, sí que puede ser útil para ver todos los datos (pares "clave/valor") que hay guardados. Para ello utilizaremos un bucle que recorra todos los datos. La propiedad length nos dirá cuantos elementos hay guardados y el método key() nos muestra los datos. El código ser parecido a éste: En este ejemplo hemos sacado todos los datos guardados en pantalla dentro de una lista. Siguiendo este mismo ejemplo no nos sería difícil hacer un bucle que borrara todos los datos que tenemos almacenados. Para ello una vez obtenida la clave se le aplicaría el método removeItem(clave). Guardar datos que no son cadenas El sistema de almacenamiento de localStorage sólo puede guardar cadenas de texto, por lo que tenemos el problema de querer guardar otro tipo de datos como números, fechas, arrays, etc. En este caso el navegador convertirá este dato a cadena de texto, por lo que cuando lo recojamos, debemos convertirlo al tipo de dato original para poder usarlo como tal. Uso actual de localstorage localStorage se ha convertido en una herramienta esencial en numerosas aplicaciones web, si bien su uso se convierte en esencial en aplicaciones web móviles encapsuladas con Apache Córdova (PhoneGap), donde muchas de ellas no necesitan grandes necesidades de almecenamiento pero sí hacer persistentes ciertas preferencias de usuario, o cachear alguna información para uso en modo offline. Gracias a localStorage no es necesario recurrir a plugins extras cuando las necesidades de almacenamiento no son excesivas. Eventos para trabajar con localstorage También podemos detectar modificaciones en localStorage ya que cada vez que ejecutamos funciones como setItem, removeItem o clear, se dispara el evento ‘storage’, pudiendo establecer un listener sobre este: La función que asociemos al evento recibirá un parámetro de tipo StorageEvent donde se nos indicará la key modificada, el valor antiguo, el nuevo y la url que propició el cambio. Depuración Según el navegador que utilicemos podremos consultar visualmente el contenido almacenado en localStorage. Algunos navegadores incorporan estos visualizadores en sus herramientas para desarrolladores, como es el caso de Chrome y Safari (Recursos -> Almacenamiento local). Otros como firefox de momento necesitan hacerlo a través de una extensión. III. MATERIAL Y EQUIPO Para la realización de la guía de práctica se requerirá lo siguiente: No. Requerimiento 1 Guía de práctica #11: JSON, localStorage y sessionStorage 2 Computadora con editor HTML instalado y navegadores 3 Memoria USB. Cantidad 1 1 1 IV. PROCEDIMIENTO Ejercicio #1: El siguiente ejemplo muestra cómo se puede utilizar un arreglo de objetos JSON para almacenar datos personales de una lista de personas. Guión 1: listanombres.html <!DOCTYPE html> <html lang="es"> <head> <title></title> <meta charset="utf-8" /> <link rel="stylesheet" href="css/grid.css" /> </head> <body> <div id="wrapper"> <header> <h1>Datos personales con JSON</h1> </header> <section> <article id="test"> <div id="info"></div> </article> </section> <script type="text/javascript" src="js/names.js"></script> </div> </body> </html> Guión 2: names.js var nombres = { "Personas": [ {"imagen" : "img/juan-robles.jpg", "nombre" : "Juan", "apellido" : "Robles", "edad" : 29, "profesion" : "Licenciado"}, {"imagen" : "img/lilian-rosales.jpg", "nombre" : "Lilian", "apellido" : "Rosales", "edad" : 27, "profesion" : "Bachiller"}, {"imagen" : "img/gustavo-gonzalez.jpg", "nombre" : "Gustavo", "apellido" : "Gonzalez", "edad" : 28, "profesion" : "Arquitecto"}, {"imagen" : "img/genesis-deras.jpg", "nombre" : "Génesis", "apellido" : "Deras", "edad" : 31, "profesion" : "Mercadóloga"}, {"imagen" : "img/reina-benitez.jpg", "nombre" : "Reina", "apellido" : "Benitez", "edad" : 25, "profesion" : "Secretaria"}, {"imagen" : "img/hugo-perez.jpg", "nombre" : "Hugo", "apellido" : "Pérez", "edad" : 34, "profesion" : "Diseñador"} ] }; //Obteniendo el elemento contenedor donde se cargarán //todos los datos del objeto JSON var div = document.getElementById("info"); div.innerHTML = volcarDatos(nombres.Personas); function volcarDatos(datos){ var total = datos.length; data = "<ul class=\"grid\">\n"; for(var i=0; i<total; i++){ data += "<li class=\"box\">\n"; data += "<div class=\"box-shadow\"></div>\n"; data += "<div class=\"box-gradient\">\n"; data += "<img src=\"" + datos[i].imagen + "\" alt=\"Avatar de " + datos[i].nombre + " " + datos[i].apellido + "\" class=\"avatar\" />\n"; data += "<h4>\nNombre: " + datos[i].nombre + " " + datos[i].apellido + "\n</h4>\n"; data += "<p>\nEdad: " + datos[i].edad + "\n<br />\n"; data += "Profesión: " + datos[i].profesion + "\n</p>\n"; data += "</div>\n"; data += "</li>\n"; } data += "</ul>\n"; return data; } Guión 3: fonts.css @font-face { font-family: 'LatoSemibold'; src: url('../fonts/Lato-Semibold.eot'); /* IE9 Compat Modes */ src: url('../fonts/Lato-Semibold.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('../fonts/Lato-Semibold.otf') format('otf'), url('../fonts/Lato-Semibold.woff') format('woff'), /* Modern Browsers */ url('../fonts/Lato-Semibold.ttf') format('truetype'); font-style: normal; font-weight: normal; text-rendering: optimizeLegibility; } @font-face { font-family: 'LatoRegular'; src: url('../fonts/Lato-Regular.eot'); /* IE9 Compat Modes */ src: url('../fonts/Lato-Regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('../fonts/Lato-Regular.otf') format('otf'), url('../fonts/Lato-Regular.woff') format('woff'), /* Modern Browsers */ url('../fonts/Lato-Regular.ttf') format('truetype'); font-style: normal; font-weight: normal; text-rendering: optimizeLegibility; } @font-face { font-family: 'LeagueGothicRegular'; src: url('../fonts/League-GothicRegular.eot'); /* IE9 Compat Modes */ src: url('../fonts/League-GothicRegular.eot?#iefix') format('embeddedopentype'), /* IE6-IE8 */ url('../fonts/League-GothicRegular.otf') format('otf'), url('../fonts/League-GothicRegular.woff') format('woff'), /* Modern Browsers */ url('../fonts/League-GothicRegular.ttf') format('truetype'); font-style: normal; font-weight: normal; text-rendering: optimizeLegibility; } Guión 4: grid.css html { height: 100%; } body { background: #efc5ca; /* Old browsers */ background: -moz-linear-gradient(top, #efc5ca 0%, #b72231 22%, #d24b5a 84%, #f18e99 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, colorstop(0%,#efc5ca), color-stop(22%,#b72231), color-stop(84%,#d24b5a), colorstop(100%,#f18e99)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, #efc5ca 0%,#b72231 22%,#d24b5a 84%,#f18e99 100%); /* Chrome10+,Safari5.1+ */ background: -o-linear-gradient(top, #efc5ca 0%,#b72231 22%,#d24b5a 84%,#f18e99 100%); /* Opera 11.10+ */ background: -ms-linear-gradient(top, #efc5ca 0%,#b72231 22%,#d24b5a 84%,#f18e99 100%); /* IE10+ */ background: linear-gradient(to bottom, #efc5ca 0%,#b72231 22%,#d24b5a 84%,#f18e99 100%); /* W3C */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#efc5ca', endColorstr='#f18e99',GradientType=0 ); /* IE6-9 */ } #wrapper { margin: 0 auto; max-width: 1120px; width: 88%; } header h1 { text-align: center; margin: 12px auto; font-family: "LeagueGothicRegular",Verdana,Helvetica,"Liberation Sans"; font-size: 3.8em; text-transform: uppercase; color: #707070; text-shadow: 5px 5px 0px #EEE, 7px 7px 0px #707070; } ul.grid li { display: inline-block; vertical-align: top; width: 168px; /* Para lograr el efecto del inline-block en navegadores IE 6 y 7 */ *display: inline; *zoom: 1; } ul.grid li h4 { color: Brown; font: Bold 0.9em "LatoSemibold",Verdana,Helvetica,"Liberation Sans"; text-align: center; } ul.grid li p { color: #393639; font: Normal 0.8em "LatoRegular",Verdana,Helvetica,"Liberation Sans"; margin: 0 9px; text-align: left; } ul.grid li img.avatar { background: #F9FCF9; border: solid 1px #B99F9F; margin: 6px 7px; padding: 6px; } ul.grid li img.avatar:hover { border: solid 1px #CCC; -moz-box-shadow: 1px 1px 5px #999; -webkit-box-shadow: 1px 1px 5px #999; box-shadow: 1px 1px 5px #999; } .box { position:relative; width: 168px; height:300px; margin: 16px auto; } .box-gradient { background: rgba(226,226,226,1); background: -moz-linear-gradient(left, rgba(226,226,226,1) 0%, rgba(219,219,219,1) 0%, rgba(209,209,209,1) 51%, rgba(222,219,222,1) 100%); background: -webkit-gradient(left top, right top, color-stop(0%, rgba(226,226,226,1)), color-stop(0%, rgba(219,219,219,1)), color-stop(51%, rgba(209,209,209,1)), color-stop(100%, rgba(222,219,222,1))); background: -webkit-linear-gradient(left, rgba(226,226,226,1) 0%, rgba(219,219,219,1) 0%, rgba(209,209,209,1) 51%, rgba(222,219,222,1) 100%); background: -o-linear-gradient(left, rgba(226,226,226,1) 0%, rgba(219,219,219,1) 0%, rgba(209,209,209,1) 51%, rgba(222,219,222,1) 100%); background: -ms-linear-gradient(left, rgba(226,226,226,1) 0%, rgba(219,219,219,1) 0%, rgba(209,209,209,1) 51%, rgba(222,219,222,1) 100%); background: linear-gradient(to right, rgba(226,226,226,1) 0%, rgba(219,219,219,1) 0%, rgba(209,209,209,1) 51%, rgba(222,219,222,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e2e2e2', endColorstr='#dedbde', GradientType=1 ); border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; height: 100%; position: absolute; width: 100%; } .box-shadow { position: absolute; left: 50%; margin: 200px 0 0 -84px; bottom: 0; width: 164px; height: 10px; background: #fff; border-radius: 290px/8px; -moz-border-radius: 290px/8px; -webkit-border-radius: 290px/8px; box-shadow: 0 10px 20px #000; -moz-box-shadow: 0 10px 20px #000; -webkit-box-shadow: 0 10px 20px #000; } Resultado: Ejercicio #2: En el siguiente ejemplo se muestra cómo utilizar el almacenamiento local para capturar datos ingresados desde un formulario, de modo que una vez presionado el botón guardar, aunque se actualice la página desde el navegador, e incluso, cuando se cierre la ventana o pestaña, el datos guardado se conservará, obteniéndolo desde la memoria local. Guión 1: almacenamientolocal.html <!DOCTYPE html> <head> <title></title> <meta charset="utf-8" /> </head> <body> <section> <article> <span id="webStorageStoredText"></span> <br /> <label for="webStorageInput">Ingrese el dato:</label> <input type="text" id="webStorageInput" name="webStorageInput" /><br /> <input type="button" id="webStorageSaveBtn" value="Guardar" /> <input type="button" id="clearWebStorage" value="Borrar" /> <span id="notCompatibleMsg" style="color:#FF0000; display:none;"> Desafortunadamente, tu navegador no tiene soporte para almacenamiento local.</span> <span id="isCompatibleMsg" style="color:#00FF00; display:none;"> ¡Felicidades, tu navegador soporta almacenamiento local!</span> </article> </section> <script type="text/javascript" src="js/savelocalstorage.js"></script> </body> </html> Guión 2: savelocalstorage.js //Verificar si el navegador utilizado posee soporte para usar localStorage. //Si no lo es advertir al usuario enviando una advertencia de no compatibilidad. if (typeof(localStorage) == "undefined") { document.getElementById("notCompatibleMsg").style.display = 'block'; } else { document.getElementById("isCompatibleMsg").style.display = 'block'; } //Obtener todos los elementos del documento que se requieren //utilizando el modelo del DOM Nivel 2. var storedTextContainer = document.getElementById("webStorageStoredText"); //Acceder al dato almacenado previamente con localStorage. var storedText = localStorage.getItem('webStorageTestInput'); var inputBox = document.getElementById("webStorageInput"); var saveBtn = document.getElementById("webStorageSaveBtn"); var clearBtn = document.getElementById("clearWebStorage"); //Verificar si el dato almacenado en el objeto localStorage es nulo. if(storedText != null){ //Si estamos aquí significa que existe un dato almacenado en localStorage. //Colocamos el datos almacenado en el elemento de la página con id storedTextContainer. storedTextContainer.innerHTML = "<strong>Dato cargado desde almacenamiento local:</strong> " + storedText; //Volver a cargar el dato almacenado en el campo de texto inputBox.value = storedText; } //Usamos el manejador de evento onclick sobre el botón Guardar para almacenar //el dato ingresado hasta el momento en el objeto localStorage. saveBtn.onclick = function(){ //Before we save this data, let's escape it so you "hackers" out there don't try anything funny! var valueToSave =inputBox.value.replace(/<\/?[^>]+>/gi, ''); //This is the way we store things in localStorage localStorage.setItem('webStorageTestInput',valueToSave); //Let the user know the text was saved. storedTextContainer.innerHTML = "Se ha almacenado correctamente '" + valueToSave + ".' Actualice la página para que observe que el dato almacenado es mostrado en el campo de formulario."; } //Borramos todo el contenido (clave y valor) almacenado en el objeto localStorage clearBtn.onclick = function(){ //Verificamos que exista dato almacenado en localStorage if(storedText != null){ localStorage.clear(); //Limpiar la caja de texto inputBox.value = ""; storedTextContainer.innerHTML = "Almacenamiento local liberado."; } } Resultado: Ejercicio #3: El siguiente ejemplo ilustra cómo hacer con canvas una pizarra de dibujo. Para dibujar dentro de la pizarra basta con presionar el botón izquierdo del ratón y sin soltarlo trazar las líneas moviéndose sobre el lienzo que representa la pizarra. El código JavaScript controla que el dibujo respete los límites de la pizarra. Si se desea terminar un trazo, debe soltar el botón izquierdo del ratón. Puede comenzar un nuevo trazo después de eso. Guión 1: formasdistintas.html <!DOCTYPE html> <html lang="es"> <head> <title>Formas de utilizar localStorage</title> <meta charset="utf-8" /> <head> <body> <section> <article> <form name="form"> <select name="methods"> <option value="api" selected="selected">API localStorage</option> <option value="array">Notación de matrices</option> <option value="object">Propiedades de objeto</option> </select><br /> <input type="button" name="seleccionar" id="seleccionar" value="Seleccionar" /> </form> </article> </section> <div id="content"></div> <script type="text/javascript" src="js/formstorage.js"></script> </body> </html> Guión 2: formstorage.js var valor; function init(){ var seleccion = document.getElementById("seleccionar"); if(seleccion.addEventListener){ seleccion.addEventListener("click", mostrar, false); } else if(seleccion.attachEvent){ seleccion.attachEvent("onclick", mostrar); } } function mostrar(){ //Determinando la opción seleccionada var opcion = document.form.methods.options[document.form.methods.selectedIndex].value; switch(opcion){ case "api": // Utilizando la Api de Local Storage, podemos guardar y luego recuperar un valor localStorage.setItem('bienvenida', 'Bienvenidos a localStorage con API de JavaScript'); valor = localStorage.getItem('bienvenida'); break; case "array": // Utilizar notación de matrices o arreglos localStorage['bienvenida'] = 'Bienvenidos, también podemos usar notación de matrices'; valor = localStorage['bienvenida']; break; case "object": // Y claro, también es válido utilizar notación de propiedades de objetos */ localStorage.bienvenida = 'Bienvenidos, igual podemos usarlo como propiedades de objeto'; valor = localStorage.bienvenida; break; default: alert("Esta opción no existe"); break; } var contenido = document.getElementById("content"); contenido.innerHTML = "<p>\nUsando : <strong>" + opcion + "</strong> - " + valor + "\n\t</p>\n"; } if(window.addEventListener){ window.addEventListener("load", init, false); } else if(window.attachEvent){ window.attachEvent("onload", init); } Ejemplo #4: El siguiente ejemplo ilustra las distintas formas de utilización del objeto localStorage para almacenar un dato simple, un objeto o un arreglo de datos. Se utiliza un formulario para ingresar dos datos como nombre y edad y luego se guardan con los botones Añadir, un dato como cadena, con el botón Guardar dato complejo se almacena como un objeto y con el botón Guardar arreglo se almacenan ambos datos como arreglo. En este último caso, puede almacenar muchos pares de datos nombre y edad. Adicionalmente, puede remover los datos almacenados con Añadir con el botón Remover o Limpiar todo el contenido del localStorage con el botón Limpiar. También se pueden restaurar el objeto o el arreglo guardado con los botones Restaurar dato complejo y Restaurar arreglo, respectivamente. Guión 1: teststorage.html <!DOCTYPE html> <html> <head> <title>Prueba de almacenamiento local</title> <meta charset="utf-8" /> <link rel="stylesheet" href="css/base.css" /> <script type="text/javascript" src="js/appform.js"></script> </head> <body> <section> <article> <form name="regestryform"> <fieldset id="myform"> <legend>Datos personales</legend> <ul class="formset"> <li> <label for="name">Nombre:</label> <input type="text" name="name" id="name" placeholder="(Su nombre)" /> </li> <li> <label for="age">Edad:</label> <input type="number" name="age" id="age" placeholder="(Su edad)" /> </li> </li> <li> <input type="button" id="add" value="Añadir" onclick="Javascript:save()"> <input type="button" id="get" value="Obtener" onclick="Javascript:obtain()"> <input type="button" id="del" value="Remover" onclick="Javascript:remove()"> <input type="button" id="clear" value="Limpiar" onclick="Javascript:clearStorage()"> </li> <li> <input type="button" id="saveC" value="Guardar dato complejo" onclick="Javascript:saveComplexData()"> <input type="button" id="restoreC" value="Restaurar dato complejo" onclick="Javascript:restoreComplexData()"> <input type="button" id="sArray" value="Guardar arreglo" onclick="Javascript:saveArrayData()"> <input type="button" id="rArray" value="Restaurar arreglo" onclick="Javascript:restoreArrayData()"> </li> </ul> </fieldset> </form> <div id="state"></div> </article> </section> </body> </html> Guión 2: appform.js var myArrayObject = []; var divState; function init() { console.log("Carga de la página finalizada."); if(typeof(Storage) == "undefined") { alert("El navegador no tiene soporte para HTML5 y almacenamiento local. Se recomienda actualizarlo."); } else { console.log("El navegador soporta tanto localStorage como sessionStorage."); divState = document.getElementById("state"); } divState = document.getElementById("state"); if(typeof(localStorage) == "undefined"){ divState.style.display = 'none'; } else{ divState.style.display = 'block'; } } function save() { var myName = document.getElementById("name"); var age = document.getElementById("age"); var msg; //Verificar si se puede utilizar localStorage en el navegador try { localStorage.setItem("name", myName.value); localStorage.setItem("age", age.value); myName.value = ""; age.value = ""; msg = "Datos guardados en el localStorage."; console.log(msg); //Mostrar al usuario mensaje de estado divState.innerHTML = "<p>" + msg + "</p>"; } catch (e) { //Verificar si el límite de almacenamiento no se ha sobrepasado if (e >= QUOTA_EXCEEDED_ERR) { console.log("Error: Límite para almacenamiento local se alcanzado."); } else { console.log("Error: Guardando en el almacenamiento local."); } } } function obtain() { var msg = "Obteniendo el dato " + localStorage.key(0) localStorage.key(1) + " desde el localStorage."; var myName = document.getElementById("name"); var age = document.getElementById("age"); console.log(msg); divState.innerHTML = "<p>" + msg + "</p>"; myName.value = localStorage.getItem("name"); age.value = localStorage.getItem("age"); } function remove() { console.log("Removiendo dato del localStorage."); localStorage.removeItem("name"); localStorage.removeItem("age"); } function clearStorage() { divState.innerHTML = ""; console.log("Borrando todo el contenido de localStorage."); localStorage.clear(); } function saveComplexData() { console.log("Guardando datos complejos a localStorage."); var myName = document.getElementById("name"); var age = document.getElementById("age"); var personObject = new Object(); personObject.name = myName.value; personObject.age = age.value; + " y ha " + localStorage.setItem("person", JSON.stringify(personObject)); } function restoreComplexData() { console.log("Restaurando datos complejos desde localStorage."); var myName = document.getElementById("name"); var age = document.getElementById("age"); var personObject = JSON.parse(localStorage.getItem("person")); myName.value = personObject.name; age.value = personObject.age; //Mostrar al usuario en el elemento DIV el contenido del objeto divState.innerHTML = "<p>Nombre: " + personObject.name + ", Edad: " + personObject.age + "</p>"; } function saveArrayData() { var myName = document.getElementById("name"); var myAge = document.getElementById("age"); //Creando el arreglo con los datos var personObject1 = new Object(); personObject1.name = myName.value; personObject1.age = parseInt(myAge.value); myArrayObject.push(personObject1); console.log("Guardando arreglo de datos en localStorage."); localStorage.setItem("persons", JSON.stringify(myArrayObject)); } function restoreArrayData() { divState.innerHTML = ""; console.log("Restaurando arreglo de datos desde localStorage."); var myArrayObject = JSON.parse(localStorage.getItem("persons")); for(var i=0; i<myArrayObject.length; i++){ var personObject = myArrayObject[i]; console.log("Nombre: " + personObject.name, "Edad: " + personObject.age); divState.innerHTML += "<p>Nombre: " + personObject.name + ", Edad: " + personObject.age + "</p>"; } } if(window.addEventListener){ window.addEventListener("load", init, false); } else if(window.attachEvent){ window.attachEvent("onload", init); } Guión 3: base.css * { margin: 0; padding: 0; outline: none; } html, body { height: 100%; width: 100%; } body { font-size: 15px; } form { background: rgba(243,226,199,1); background: -moz-linear-gradient(left, rgba(243,226,199,1) 0%, rgba(193,158,103,1) 45%, rgba(182,141,76,1) 51%, rgba(233,212,179,1) 100%); background: -webkit-gradient(left top, right top, color-stop(0%, rgba(243,226,199,1)), color-stop(45%, rgba(193,158,103,1)), color-stop(51%, rgba(182,141,76,1)), color-stop(100%, rgba(233,212,179,1))); background: -webkit-linear-gradient(left, rgba(243,226,199,1) 0%, rgba(193,158,103,1) 45%, rgba(182,141,76,1) 51%, rgba(233,212,179,1) 100%); background: -o-linear-gradient(left, rgba(243,226,199,1) 0%, rgba(193,158,103,1) 45%, rgba(182,141,76,1) 51%, rgba(233,212,179,1) 100%); background: -ms-linear-gradient(left, rgba(243,226,199,1) 0%, rgba(193,158,103,1) 45%, rgba(182,141,76,1) 51%, rgba(233,212,179,1) 100%); background: linear-gradient(to right, rgba(243,226,199,1) 0%, rgba(193,158,103,1) 45%, rgba(182,141,76,1) 51%, rgba(233,212,179,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f3e2c7', endColorstr='#e9d4b3', GradientType=1 ); border: 1px solid #999; border: inset 1px solid #333; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; -webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3); -moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3); box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3); font: Normal 1.2em Tahoma,Geneva,"Liberation Sans"; margin: auto; height:auto; line-height: 24px; -webkit-border-radius: 10px; -moz-border-radius: 10px; padding:10px; position: relative; text-decoration: none; width:740px; } .formset li { clear: both; display: block; margin: 16px 6px; } label { color: #082460; } input[type="text"], input[type="number"] { border: 1px solid #999; -webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3); -moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3); box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3); display: block; font-size: 1em; height: 30px; width: 98%; } textarea { height: 150px; width: 375px; } input[type="button"] { -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; border: 1p solid #999; background: rgba(44,68,138,1); background: -moz-linear-gradient(top, rgba(44,68,138,1) 0%, rgba(24,45,99,1) 46%, rgba(15,36,89,1) 50%, rgba(11,22,66,1) 100%); background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(44,68,138,1)), color-stop(46%, rgba(24,45,99,1)), color-stop(50%, rgba(15,36,89,1)), color-stop(100%, rgba(11,22,66,1))); background: -webkit-linear-gradient(top, rgba(44,68,138,1) 0%, rgba(24,45,99,1) 46%, rgba(15,36,89,1) 50%, rgba(11,22,66,1) 100%); background: -o-linear-gradient(top, rgba(44,68,138,1) 0%, rgba(24,45,99,1) 46%, rgba(15,36,89,1) 50%, rgba(11,22,66,1) 100%); background: -ms-linear-gradient(top, rgba(44,68,138,1) 0%, rgba(24,45,99,1) 46%, rgba(15,36,89,1) 50%, rgba(11,22,66,1) 100%); background: linear-gradient(to bottom, rgba(44,68,138,1) 0%, rgba(24,45,99,1) 46%, rgba(15,36,89,1) 50%, rgba(11,22,66,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#2c448a', endColorstr='#0b1642', GradientType=0 ); color: #ccc; display: inline-block; margin-right: 3px; font: Bold 0.7em Tahoma,Geneva,"Liberation Sans"; height: 34px; vertical-align: top; width: 172px; } input[type="button"]:hover { background: rgba(5,23,94,1); background: -moz-linear-gradient(top, rgba(5,23,94,1) 0%, rgba(8,39,112,1) 50%, rgba(20,52,133,1) 54%, rgba(27,59,148,1) 100%); background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(5,23,94,1)), color-stop(50%, rgba(8,39,112,1)), color-stop(54%, rgba(20,52,133,1)), color-stop(100%, rgba(27,59,148,1))); background: -webkit-linear-gradient(top, rgba(5,23,94,1) 0%, rgba(8,39,112,1) 50%, rgba(20,52,133,1) 54%, rgba(27,59,148,1) 100%); background: -o-linear-gradient(top, rgba(5,23,94,1) 0%, rgba(8,39,112,1) 50%, rgba(20,52,133,1) 54%, rgba(27,59,148,1) 100%); background: -ms-linear-gradient(top, rgba(5,23,94,1) 0%, rgba(8,39,112,1) 50%, rgba(20,52,133,1) 54%, rgba(27,59,148,1) 100%); background: linear-gradient(to bottom, rgba(5,23,94,1) 0%, rgba(8,39,112,1) 50%, rgba(20,52,133,1) 54%, rgba(27,59,148,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#05175e', endColorstr='#1b3b94', GradientType=0 ); color:#f6f6f6; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; /* IE 8 */ filter: alpha(opacity=85); /* IE 5-7 */ -moz-opacity: 0.85; /* Netscape and old Firefox */ -khtml-opacity: 0.85; /* Old Safaris */ opacity: 0.85; /* Standar browsers */ } #state { background: rgba(44,68,138,1); background: -moz-linear-gradient(top, rgba(44,68,138,1) 0%, rgba(24,45,99,1) 46%, rgba(15,36,89,1) 50%, rgba(11,22,66,1) 100%); background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(44,68,138,1)), color-stop(46%, rgba(24,45,99,1)), color-stop(50%, rgba(15,36,89,1)), color-stop(100%, rgba(11,22,66,1))); background: -webkit-linear-gradient(top, rgba(44,68,138,1) 0%, rgba(24,45,99,1) 46%, rgba(15,36,89,1) 50%, rgba(11,22,66,1) 100%); background: -o-linear-gradient(top, rgba(44,68,138,1) 0%, rgba(24,45,99,1) 46%, rgba(15,36,89,1) 50%, rgba(11,22,66,1) 100%); background: -ms-linear-gradient(top, rgba(44,68,138,1) 0%, rgba(24,45,99,1) 46%, rgba(15,36,89,1) 50%, rgba(11,22,66,1) 100%); background: linear-gradient(to bottom, rgba(44,68,138,1) 0%, rgba(24,45,99,1) 46%, rgba(15,36,89,1) 50%, rgba(11,22,66,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#2c448a', endColorstr='#0b1642', GradientType=0 ); border: 3px inset rgba(243,226,199,1); -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; -webkit-box-shadow: 5px 5px 3px 3px rgba(31,24,10,1); -moz-box-shadow: 5px 5px 3px 3px rgba(31,24,10,1); box-shadow: 5px 5px 3px 3px rgba(31,24,10,1); color: rgba(243,226,199,1); font: Bold 0.85em Tahoma,Helvetica,"Liberation Sans"; height: auto; margin: 12px auto; padding: 18px 24px; width: 710px; } Resultado: Ejercicio #5: El siguiente ejemplo muestra cómo crear un reproductor de música para web usando el elemento de HTML5 audio y sus subelementos asociados source donde se indican los archivos fuente. Como mínimo, para lograr compatibilidad entre navegadores, debería usar dos formatos de audio que son el mp3 y el ogg. Para realizar este ejemplo, se utiliza un arreglo de objetos JSON, con la información de las canciones que contiene el reproductor. Lógicamente, debería almacenar los archivos de audio en ambos formatos (mp3 y ogg). La conversión de mp3 a ogg o viceversa, puede hacerse a través del sitio web http://midia.io. El reproductor permite cambiarse de canción dando clic en el título de cada canción, o comenzar reproduciendo la primera canción dando clic en el botón play. Además, se proporcionan controles para cambiar el volumen. Guión 1: reproductor.html <!DOCTYPE html> <html lang="es"> <head> <title>Reproductor de audio</title> <meta charset="utf-8" /> <link rel="stylesheet" href="css/player.css" /> <script type="text/javascript" src="js/CSSClass.js"></script> </head> <body> <header id="fire"> <h1>Reproductor</h1> </header> <a href="javascript:void(0);" id="play" class="audio_control"></a> <a href="javascript:void(0);" id="pause" class="audio_control"></a> <span id="currentTime" class="audio_control">00:00:00</span> <span id="duration" class="audio_control">00:00:00</span> <a href="#" id="volDown" class="audio_control"></a> <a href="#" id="volUp" class="audio_control"></a> <span id="vol" class="audio_control"></span> <audio id="player" preload="auto" controls="controls"> <source src="songs/mp3/Alex_Gaudino_-_Destination_calabria.mp3"></source> <source src="songs/ogg/Alex_Gaudino_-_Destination_calabria.ogg"></source> </audio> <section> <article id="container"> </article> </section> <div id="error"></div> <script type="text/javascript" src="js/player.js"></script> </body> </html> Guión 2: CSSClass.js /************************************************************************** * CSSClass.js: utilidades para manipular la clase CSS de un elemento HTML * * Descripción: el módulo define un sólo objeto de espacios de nombres al * * que se denominará CSSClass. Este objeto contiene funciones * * de utilidad para trabajar con el atributo class (propiedad * * className) de elementos HTML. * * Argumentos: Todas las funciones aceptan dos argumentos: el elemento e * * que se va a probar o a manipular y la clase CSS c que se * * va a probar, añadir o eliminar. * **************************************************************************/ //Crear un objeto de espacio de nombres usando notación de literal de objeto var CSSClass = {}; //Sintaxis declarativa para objetos //Devolver true si el elemento e es miembro de la clase c //y devolver false en caso contrario CSSClass.is = function(e, c){ if(typeof e == "string") e = document.getElementById(e); //Antes de realizar una búsqueda con regexp, optimizar casos comunes var classes = e.className; if(!classes) return false; //No es miembro de ninguna clase if(classes == c) return true; //Es miembro sólo de una clase //En todos los demás casos, utilizar una expresión regular //para buscar c como palabra usando \b para coincidir con //cualquier límite de palabra. Note que la expresión devolverá //true o false dependiendo si el método search() encuentra o no //coincidencia con el patrón return e.className.search("\\b" + c + "\\b") != -1; }; //Añadir la clase c al className del elemento e, si no está ya incluido CSSClass.add = function(e, c){ if(typeof e == "string") e = document.getElementById(e); //Id del elemento if(CSSClass.is(e, c)) return; //Si ya es miembro no hacer nada if(e.className) c = " " + c //Si es necesario utilizar separador de //espacio en blanco si ya había otra clase //Añadir la nueva clase al final e.className += c; }; //Eliminar todas las apariciones de la clase c del className //del elemento e CSSClass.remove = function(e, c){ if(typeof e == "string") e = document.getElementById(e); //Buscar en className todas las apariciones de c y reemplazarlas //con "". Se utilizará \s* para coincidir con cualquier número //de caracteres de espacio en blanco y el modificador global "g" //para hacer que la expresión regular coincida con cualquier //número de apariciones. e.className = e.className.replace(new RegExp("\\b"+c+"\\b\\s*", "g"), ""); } Guión 3: player.js //Variables que utilizará la aplicación var player = false; var canvas = false; var context = false; var paused = false; //Si existe el soporte para el elemento audio creamos //el objeto JSON con la información de las canciones var songs = [ {"track" : 1, "title" : "Alex Gaudino", "artist" : "Destination calabria", "duration" : "3:02", "mp3file" : "Alex_Gaudino_-_Destination_calabria.mp3", "oggfile" : "Alex_Gaudino_-_Destination_calabria.ogg"}, {"track" : 2, "title" : "Route 101", "artist" : "Herb Alpert", "duration" : "3:18", "mp3file" : "Herb_Alpert_-_ Route_101.mp3", "oggfile" : "Herb_Alpert_-_ Route_101.ogg"}, {"track" : 3, "title" : "Me and you and a dog named boo", "artist" : "Lobo", "duration" : "2:56", "mp3file" : "Lobo_-_Me_and_you_and_a_dog_named_boo.mp3", "oggfile" : "Lobo_-_Me_and_you_and_a_dog_named_boo.ogg"} ]; var path = ""; var updateCanvas = function(percent){ //Obtenemos la anchura del canvas var w = canvas.width * percent/100; //Dibujamos un rectángulo relleno de blanco (limpiamos la imagen) context.fillStyle = "#FFFFFF"; context.fillRect(0, 0, canvas.width, canvas.height); //Dibujamos un rectángulo de relleno gris context.fillStyle = "#BEBEBE"; context.fillRect(0, 0, w, canvas.height); //Lo envolvemos con una caja de color naranja context.strokeStyle = "#060606"; context.strokeRect(0, 0, canvas.width, canvas.height); } var canvasClicked = function(event){ //Hacemos una regla de tres para colocar el timer del reproductor //en un tiempo directamente proporcional a la zona que hemos pinchado player.currentTime = player.duration * event.offsetX/canvas.width; } //Convierte segundos (double) a hh:mm:ss var toHMS = function(it){ if(isNaN(it)){ return "00:00:00"; } var hours = parseInt(it/3600); var minutes = parseInt((it%3600)/60); var seconds = parseInt((it%3600)%60); return ((hours < 10?"0" + hours:hours) + ":" + (minutes minutes:minutes) + ":" + (seconds < 10?"0" + seconds:seconds)); } < 10?"0" + var pause = function(){ //Pausamos la reproducción player.pause(); paused = true; //Escondemos el pause y mostramos el play = display o visibility var pausa = document.getElementById("pause"); var play = document.getElementById("play"); pausa.style.display = "none"; play.style.display = "inline-block"; } var play = function(e){ e.preventDefault(); //Determinar si se hizo click en la lista de canciones o en el botón play var currentTrack; var currentLink; if(this.id == "play" && currentTrack === undefined){ currentTrack = 0; } else { currentTrack = this.id; //alert(currentLink); } //Cargar la canción que se va a reproducir dinámicamente var sourceElement; var songFile; var formats = ["mp3", "ogg"]; path = "songs/"; var source = ""; for(var j=0; j<formats.length; j++){ var audioElement = document.getElementById("player"); audioElement.innerHTML = ""; //Creando el elemento source dinámicamente y cargar //la canción en su atributo src sourceElement = document.createElement("source"); sourceElement.setAttribute("src", path + songs[currentTrack].mp3file); audioElement.appendChild(sourceElement); sourceElement = document.createElement("source"); sourceElement.setAttribute("src", path + songs[currentTrack].oggfile); audioElement.appendChild(sourceElement); //Obteniendo el elemento audio de la página donde será //agregado el elemento source recién creado } //Iniciamos la reproducción if(this.id != "play"){ player.load(); currentLink = document.getElementById(this.id); CSSClass.add(currentLink,"currentTrack"); } player.play(); "mp3/" + "ogg/" + paused = false; //Escondemos el play y mostramos el pause = display o visibility var pausa = document.getElementById("pause"); var play = document.getElementById("play"); pausa.style.display = "inline-block"; play.style.display = "none"; } var updateTimes = function(){ //Actualizamos el display de tiempo transcurrido = innerHTML var tiempoTranscurrido = document.getElementById("currentTime"); tiempoTranscurrido.innerHTML = toHMS(player.currentTime); //La línea se rellenará con el porcentaje de tiempo transcurrido updateCanvas(parseInt(player.currentTime * 100/player.duration)); } var addVol = function(inc){ //Añadimos un incremento al volumen actual player.volume += inc; //Actualizamos el display de volumen = innerHTML var volumen = document.getElementById("vol"); volumen.innerHTML = parseInt(player.volume*100); } // var init = function(){ //Creando el elemento canvas para la barra de avance de la canción var playerbar = document.createElement("canvas"); var contenedor = document.getElementById("container"); contenedor.innerHTML = ""; if(playerbar){ playerbar.setAttribute("id", "timer"); playerbar.setAttribute("width", "400px"); playerbar.setAttribute("height", "12px"); contenedor.appendChild(playerbar); //Inicializamos el player player = document.getElementById("player"); //Capturando todos los botones de control reproductor var avance = document.getElementById("play"); var pausa = document.getElementById("pause"); var subirVolumen = document.getElementById("volUp"); var bajarVolumen = document.getElementById("volDown"); } else { var errormsg = document.getElementById("error"); errormsg.innerHTML = "<p>Se requiere de un navegador con soporte de HTML5 para cargar el reproductor.</p>"; return; } //Determinar el soporte para elemento audio del navegador var supportsAudio = document.createElement('audio').canPlayType; if(supportsAudio){ //Creando dinámicamente un elemento div con id playlist var playlist = document.createElement("div"); playlist.setAttribute("id", "playlist"); contenedor.appendChild(playlist); //Agregar un elemento ul al div con id playlist var ullist = document.createElement("ul"); playlist.appendChild(ullist); //Creando el número de elementos li para cada una de las canciones //definidas en el objeto JSON. Nos auxiliamos de la propiedad length //para determinar cuántos elementos li serán necesarios. var tracknumber, songtitle, artistname, linodetext, songtextnode; for(i=0; i<songs.length; i++){ var liitem = document.createElement("li"); var linktosong = document.createElement("a"); linktosong.setAttribute("href", "javascript:void(0);"); linktosong.setAttribute("class", "playlistitem"); linktosong.setAttribute("id", i.toString()); ullist.appendChild(liitem); //Datos de la canción que servirán para agregar el nodo de texto tracknumber = songs[i].track; songtitle = songs[i].title; artistname = songs[i].artist; //Agregando el elemento de enlace al elemento li liitem.appendChild(linktosong); //Construyendo el nodo de texto con los datos obtenidos del objeto JSON //y agregarlo al elemento de enlace linodetext = tracknumber + ". " + songtitle + " - " + artistname; songtextnode = document.createTextNode(linodetext); linktosong.appendChild(songtextnode); var numbertrack = linktosong.getAttribute("id"); if(linktosong.addEventListener){ linktosong.addEventListener("click", play, false); } else if(linktosong.attachEvent){ linktosong.attachEvent("onclick", play); } } } else { var errormsg = document.getElementById("error"); errormsg.innerHTML = "<p>Se requiere de un navegador con soporte de HTML5 para cargar el reproductor.</p>"; return; } //Asociamos eventos a los botones de play y pause if(avance.addEventListener){ avance.addEventListener("click", play, false); } else if(play.attachEvent){ avance.attachEvent("onclick", play); } if(pausa.addEventListener){ pausa.addEventListener("click", pause, false); } else if(pausa.attachEvent){ pausa.attachEvent("onclick", pause); } //Asociamos eventos a los botones para subir y bajar volumen if(subirVolumen.addEventListener){ subirVolumen.addEventListener("click", function(){addVol(0.01)}, false); } else if(subirVolumen.attachEvent){ subirVolumen.attachEvent("onclick", function(){addVol(0.01)}); } if(bajarVolumen.addEventListener){ bajarVolumen.addEventListener("click", function(){addVol(-0.01)}, false); } else if(bajarVolumen.attachEvent){ bajarVolumen.attachEvent("onclick", function(){addVol(-0.01)}); } //Definimos la duración de la pista de audio, así como el valor del volumen (de 0 a 100) var duracion = document.getElementById("duration"); var volumen = document.getElementById("vol"); duracion.innerHTML = toHMS(player.duration); volumen.innerHTML = parseInt(player.volume*100); //Actualizamos cada 100ms setInterval(function(){ updateTimes(); }, 100); //Inicializamos el canvas canvas = document.getElementById('timer'); if(canvas.addEventListener){ canvas.addEventListener("click", canvasClicked, false); } else if(canvas.attachEvent){ canvas.attachEvent("onclick", canvasClicked); } context = canvas.getContext('2d'); }; if(window.addEventListener){ window.addEventListener("load", function(){ var controls = document.getElementsByClassName("audio_control"); for(var i=0; i<controls.length; i++){ if(window.addEventListener){ window.addEventListener("click", function(event){ event.preventDefault(); }, false); } else if(window.attachEvent){ window.attachEvent("onclick", function(event){ event.preventDefault(); }); } } //Lanzamos la función init cuando se hayan cargado los metadatos var vid = document.getElementById("player"); vid.onloadedmetadata = init; }, false); } else if(window.attachEvent){ window.attachEvent("onload", function(){ var controls = document.getElementsByClassName("audio_control"); for(var i=0; i<controls.length; i++){ if(window.attachEvent){ window.attachEvent("click", function(event){ event.preventDefault(); }, false); } else if(window.attachEvent){ window.attachEvent("onclick", function(event){ event.preventDefault(); }); } } //Lanzamos la función init cuando se hayan cargado los metadatos var vid = document.getElementById("player"); vid.onloadedmetadata = init; }); } Guión 4: fonts.css @font-face { font-family: 'LeagueGothicRegular'; src: url('../fonts/League_Gothic.eot'); /* IE9 Compat Modes */ src: url('../fonts/League_Gothic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('../fonts/League_Gothic.woff') format('woff'), /* Modern Browsers */ url('../fonts/League_Gothic.ttf') format('truetype'), url('../fonts/League_Gothic.svg#LeagueGothicRegular') format('svg'); font-style: normal; font-weight: normal; text-rendering: optimizeLegibility; } Guión 5: player.css /* Resetear estilos de navegador */ * { border: 0; margin: 0; padding: 0; outline: none; } html, body { height: 100%; width: 100%; } body { font-size: 16px; } #fire { height: auto; background: none repeat scroll 0% 0% #000; width: 400px; } #fire h1 { color: #FFF; font: Bold 2.2em "LeagueGothicRegular",Tahoma,Helvetica,"Liberation Sans"; margin: 0 auto; text-align: center; text-transform: uppercase; text-shadow: 0px 0px 20px #FEFCC9, 10px -10px 30px #FEEC85, -20px -20px 40px #FFAE34, 20px -40px 50px #EC760C, -20px -60px 60px #CD4606, 0px -80px 70px #973716, 10px -90px 80px #451B0E; } /* Enviar el control de audio a una posición inaccesible */ audio { display: none; } /* Clase de los enlaces a las canciones del playlist */ .audio_control { background: url(../img/player-controls.jpg) 0 0; display: inline-block; font: Bold 1.5em "LeagueGothicRegular"; height: 42px; line-height: 42px; text-align: center; text-decoration: none; color: #222; text-shadow: 0px 2px 3px #555; vertical-align: top; width: 45px; } /* Estilos para los botones del reproductor */ #play { background-position: -26px 1px; overflow: hidden; } #pause { background-position: -27px 162px; display: none; overflow: hidden; } #volUp { background-position: -28px 122px; overflow: hidden; } #volDown { background-position: -27px 82px; overflow: hidden; } /* Estilos para los estados hover y active de los botones del reproductor */ #play:hover, #play:active { background-position: -125px 1px; cursor: pointer; overflow: hidden; } #pause:hover, #pause:active { background-position: -127px -79px; cursor: pointer; overflow: hidden; } #volUp:hover, #volUp:active { background-position: -127px 122px; cursor: pointer; overflow: hidden; } #volDown:hover, #volDown:active { background-position: -127px 82px; cursor: pointer; overflow: hidden; } /* Estilos para indicadores de tiempo transcurrido, tiempo total de la canción y volumen */ #currentTime { background-position: -28px 42px; width: 100px; } #duration { background-position: -28px 283px; width: 100px; } #vol { background-position: -28px 42px; } #currentTime:hover, #current:active { background-position: -28px 283px; color: #e9e9e9; } #duration:hover, #duration:active { background-position: -28px 283px; color: #e9e9e9; } #vol:hover, #vol:active { background-position: -28px 283px; color: #e9e9e9; } /* Estilos para la lista de reproducción donde se muestran las canciones */ #playlist ul { background: #3a3a3a; /* Old browsers */ background: -moz-linear-gradient(top, #3a3a3a 0%, #303030 22%, #2c2c2c 50%, #2b2b2b 50%, #1c1c1c 78%, #131313 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, colorstop(0%,#3a3a3a), color-stop(22%,#303030), color-stop(50%,#2c2c2c), colorstop(50%,#2b2b2b), color-stop(78%,#1c1c1c), color-stop(100%,#131313)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, #3a3a3a 0%,#303030 22%,#2c2c2c 50%,#2b2b2b 50%,#1c1c1c 78%,#131313 100%); /* Chrome10+,Safari5.1+ */ background: -o-linear-gradient(top, #3a3a3a 0%,#303030 22%,#2c2c2c 50%,#2b2b2b 50%,#1c1c1c 78%,#131313 100%); /* Opera 11.10+ */ background: -ms-linear-gradient(top, #3a3a3a 0%,#303030 22%,#2c2c2c 50%,#2b2b2b 50%,#1c1c1c 78%,#131313 100%); /* IE10+ */ background: linear-gradient(to bottom, #3a3a3a 0%,#303030 22%,#2c2c2c 50%,#2b2b2b 50%,#1c1c1c 78%,#131313 100%); /* W3C */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3a3a3a', endColorstr='#131313',GradientType=0 ); /* IE6-9 */ list-style: none; height: auto; width: 400px; } #playlist ul li a { color: #ededed; display: block; font: normal 0.75em "LeagueGothicRegular",Tahoma,Helvetica,"Liberation Sans"; text-decoration: none; text-shadow: 0px 2px 3px #555; padding: 4px 8px; vertical-align: top; width: 96.1%; } #playlist ul li a:hover, #playlist ul li a:active, .currentTrack { background: #919b9e; /* Old browsers */ background: -moz-linear-gradient(top, #919b9e 0%, #6e7774 50%, #747c7c 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, colorstop(0%,#919b9e), color-stop(50%,#6e7774), color-stop(100%,#747c7c)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, #919b9e 0%,#6e7774 50%,#747c7c 100%); /* Chrome10+,Safari5.1+ */ background: -o-linear-gradient(top, #919b9e 0%,#6e7774 50%,#747c7c 100%); /* Opera 11.10+ */ background: -ms-linear-gradient(top, #919b9e 0%,#6e7774 50%,#747c7c 100%); /* IE10+ */ background: linear-gradient(to bottom, #919b9e 0%,#6e7774 50%,#747c7c 100%); /* W3C */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#919b9e', endColorstr='#747c7c',GradientType=0 ); /* IE6-9 */ color: #fcfa66; overflow: hidden; text-shadow: 0px 2px 3px #555; } Resultado: V. ANÁLISIS DE RESULTADOS 1. 2. Utilizando localStorage y sessionStorage realice un ejemplo que le permita almacenar localmente los datos que se van ingresando en un formulario cada cierto número de segundos (por ejemplo, cada 3 o 5 segundos). De modo que si se actualiza la página, el formulario no pierda los datos que habían sido almacenados hasta ese momento. Primero, realice el ejemplo, utilizando localStorage en un archivo .js que puede llamar localStorage.js. Luego, realice otro script donde implementará la misma solución con sessionStorage y guárdelo en un archivo que puede nombrar sessionStorage.js. Para probar cada uno escriba dos elementos script uno a continuación del otro, pero con uno comentado y el otro habilitado. El formulario debe contener un campo input de tipo text para el nombre completo, otro campo select-option para mostrar el país con los países de centroamérica y un campo textarea para presentar una pequeña biografía. Además, debe incluir un botón para enviar el formulario que cuando sea presionado llame mediante manejo de evento DOM Nivel 2 al método o función que almacene los datos ingresados en el localStorage o en el sessionStorage, dependiendo de cuál script tenga habilitado en el código HTML. En el ejemplo del reproductor, intente crear un elemento DIV en donde debe mostrar el título y el artista de la canción que se está reproduciendo. Muéstrelo mediante un efecto de desplazamiento de modo que se vea que va pasando el nombre de la canción y que al terminar de pasar vuelve a iniciar el desplazamiento sobre el control. Coloque este elemento entre el DIV que muestra la palabra REPRODUCTOR y los botones de los controles del reproductor. VI. BIBLIOGRAFÍA Paul Deitel/Harvey Deitel/Abbey Deitel. Internet & World Wide Web. 1ra Edición. Editorial Pearson. 2014. México. Documentación oficial de JavaScript de Mozilla Developer Network: https://developer.mozilla.org/es/docs/DOM/Almacenamiento#localStorage. Artículos del sitio web de maestros del web sobre localStorage: http://www.maestrosdelweb.com/tutorial-local-session-storage/. Artículo del sitio web de aprende web: http://aprende-web.net/NT/html5/html5_9.php. Artículo sobre local Storage de Alfonso Marín, disponible en: http://alfonsomarin.com/desarrollo-web/articulos/localstorage.
© Copyright 2024