Presentación en PDF

Anuncio
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
TEMA 3 A: INTRODUCCIÓN AL DOM
1.- ¿Qué es el DOM?...................................................................................................... 2
1.1.- DOM y JavaScript ............................................................................................... 2
1.3.-¿Cómo se accede al DOM?................................................................................. 3
2. Instalar una consola.................................................................................................... 4
3. Averiguar la versión DOM de Explorer ....................................................................... 5
4.- El DOM de XML en Firefox........................................................................................ 6
5.- XML en plataformas cruzadas................................................................................... 7
6.- Carga de un documento XML (o html) ...................................................................... 8
1
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
1.- ¿Qué es el DOM?
(http://developer.mozilla.org/es/docs/Referencia_DOM_de_Gecko:Introducci%C3%B3n)
El modelo de objeto de documento (DOM) es una interfaz de programación para los
documentos HTML y XML. Facilita una representación estructurada del documento y
define de qué manera los programas pueden acceder, al fin de modificar, tanto su
estructura, estilo y contenido. El DOM da una representación del documento como un
grupo de nodos y objetos estructurados que tienen propiedades y métodos.
Esencialmente, conecta las páginas web a scripts o lenguajes de programación.
Una página web es un documento. Éste documento puede exhibirse en la ventana de
un navegador o también como código fuente HTML. Pero, en los dos casos, es el
mismo documento. El modelo de objeto de documento (DOM) proporciona otras
formas de presentar, guarda y manipular este mismo documento. El DOM es una
representación completamente orientada al objeto de la página web y puede ser
modificado con un lenguaje de script como JavaScript.
El W3C DOM estándar forma la base del funcionamiento del DOM en muchos
navegadores modernos. Varios navegadores ofrecen extensiones más allá del
estándar W3C, hay que ir con extremo cuidado al utilizarlas en la web, ya que los
documentos pueden ser consultados por navegadores que tienen DOMs diferentes.
Por ejemplo, el DOM de W3C especifica que el método getElementsByTagName en el
código de abajo debe devolver una lista de todos los elementos <P> del documento:
paragraphs = document.getElementsByTagName("P");
// paragraphs[0] es el primer elemento <p>
// paragraphs[1] es el segundo elemento <p>, etc.
alert(paragraphs[0].nodeName);
Todas las propiedades, métodos y eventos disponibles para la manipulación y la
creación de páginas web está organizado dentro de objetos. Un ejemplo: el objeto
document representa al documento mismo, el objeto table hace funcionar la interfaz
especial HTMLTableElement del DOM para acceder a tablas HTML, y así
sucesivamente.
1.1.- DOM y JavaScript
El ejemplo de abajo es JavaScript. Pero utiliza el DOM para acceder al documento y a
sus elementos. El DOM no es un lenguaje de programación pero sin él, el lenguaje
JavaScript no tiene ningún modelo o noción de las páginas web, de la páginas XML ni
de los elementos con los cuales es usualmente relacionado. Cada elemento -"el
documento íntegro, el título, las tablas dentro del documento, los títulos de las tablas,
el texto dentro de las celdas de las tablas"- es parte del modelo de objeto del
documento para cada documento, así se puede acceder y manipularlos utilizando el
DOM y un lenguaje de escritura, como JavaScript.
El contenido de la página es almacenado en DOM y el acceso y la manipulación se
hace vía JavaScript, podría representarse aproximadamente así:
API(web o página XML) = DOM + JS(lenguaje de script)
El DOM fue diseñado para ser independiente de cualquier lenguaje de programación
2
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
particular, hace que la presentación estructural del documento sea disponible desde
un simple y consistente API.
1.3.-¿Cómo se accede al DOM?
Los diferentes navegadores tienen directrices DOM distintas, y éstas directrices tienen
diversos grados de conformidad al actual estándar DOM, pero todos los navegadores
web usan el modelo de objeto de documento para hacer accesibles las páginas web al
script.
Cuando se crea un script –esté en un elemento <SCRIPT> o incluido en una página
web por la instrucción de cargar un script– inmediatamente está disponible para usarlo
con el API, accediendo así a los elementos documento o ventana, para manipular el
documento mismo o sus diferentes partes, las cuales son los varios elementos de una
página web.
La programación DOM hace algo tan simple como lo siguiente, lo cual abre un
mensaje de alerta usando la función alert() desde el objeto ventana, o permite
métodos DOM más sofisticados para crear realmente un nuevo contenido, como en el
largo ejemplo de más abajo.
<body onload="window.alert('Hola clase');">
El ejemplo siguiente muestra la función a ejecutar cuando el documento se está
cargando (y que el DOM completo es disponible para su uso). Esta función crea un
nuevo elemento H1, le pone texto y después lo agrega al árbol del documento:
<html>
<head>
<script>
// ejecuta esta función cuando la página se carga
window.onload = function() {
// crea un par de elementos
// en otra página HTML vacía
heading = document.createElement("h1");
heading_text = document.createTextNode("Cabeza grande!");
heading.appendChild(heading_text);
document.body.appendChild(heading);
}
</script>
</head>
<body>
</body>
</html>
3
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
2. Instalar una consola
Dada las características del curso mejor que usar la función Alert de Javascript vamos
a crear una consola por la que obtener los mensajes. Con esto evitaremos la molesta
detención de la ejecución del código cada vez que queremos observar que está
haciendo nuestro script.
De momento este código será un ejemplo de DOM. Más adelante irá apareciendo el
significado de cada instrucción.
Función de Javascript para consola:
function consola(txt){
var con = document.getElementById("consola");
con.innerHTML += txt + "<hr> ";
}
Simplemente hemos hecho referencia a un elemento cuyo Id es “consola”. Por ello
necesitamos que el código tenga esta línea:
<div id="consola"></div>
La siguiente instrucción hace que el contenido del elemento encontrado (un DIV) sea
HTML y que sea el que tenía más el que le indiquemos. Hemos puesto como
separador una línea.
Para probar:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Untitled</title>
<script>
function consola(txt){
var con = document.getElementById("consola");
con.innerHTML += txt + "<hr> ";
}
</script>
</head>
<body onLoad="consola('hola mundo')">
<div id="consola"></div>
</body>
</html>
Nota: Para que funcione la función primero se debe haber cargado el documento, sino
no encontrará la etiqueta <DIV>.
4
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
3. Averiguar la versión DOM de Explorer
Para crear un objeto ActiveX en JavaScript, Microsoft implemento una nueva clase
llamada ActiveXObject que puede utilizarse para instanciar cualquier número de
objetos ActiveX.
Su constructor acepta un argumento, una cadena con la versión del objeto ActiveX que
se desea crear. En ese caso, es la versión del documento XML.
El primer objeto ActiveX del modelo DOM de XML se denominó Microsoft. XmlDom y
se creaba así:
var oXmlDom = new ActiveXObject("Microsoft.XmlDom");
Los objetos DOM de XML más recientes se comportan como cualquier otro objeto
DOM, permitiéndonos recorrer el árbol del modelo DOM y manipular nodos DOM.
Dado que existen 6 versiones diferentes siempre desearemos utilizar la más reciente,
es muy útil emplear una función para determinar qué versión podemos usar.
Haciéndolo, nos aseguramos de disponer del soporte más actualizado y del mejor
rendimiento.
function creaDocumento(){
//Creo array de versiones
var aVersion = "MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.5.0",
"MSXML2.DOMDocument.4.0","MSXML2.DOMDocument.3.0",
"MSXMI.2.DOMDocument", "Microsoft.XmlDom"];
//Recorro en búsqueda
for (var i =0;i < aVersion.length; i++)
{
try {
var oXmlDom = new ActiveXObject (aVersion[i]);
consola(aVersion[i]);
return oXmlDom;
}
catch (oError){
consola(oError.description + " " + oError);
}
}
throw new Error("MSXML no está instalado");
}
Esta función recorre toda la matriz aVersion que contiene las cadenas de versión de
los distintos documentos DOM MSXML. Empieza el recorrido con la versión más
reciente, DOMDocument.6.0, e intenta (try) crear el documento DOM. Si la creación
del objeto tiene éxito, se devuelve y creaDocumento() existe. Además escribe el
nombre de la versión creada en la consola.
Si falla (catch) , se produce un error que se depura en el bloque try..catch, de forma
que el bucle continúa. En este caso se escribe en la consola la descripción del error.
Como el tratamiento es diferente en Explorer y Mozilla se apaña con una suma de
ambas interpretaciones para que se pueda leer cual es el error.
Si falla la creación del documento MSXML, se genera un error por Javascript (en caso
de Mozilla, claro) indicando que MSXML no está instalado.
5
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
Para que funciones debemos hacer algo como:
function enCarga() {
var oXlmDom = creaDocumento();
}
En la práctica sólo comprobamos si soporta la versión 4, en caso contrario tomamos
Microsoft.XmlDom
4.- El DOM de XML en Firefox
Cuando llega la hora de implementar el DOM de XML en Mozilla Firefox, los
desarrolladores adoptan un método de aproximación más centrado en los estándares
convirtiéndolo en parte de una implementación de JavaScript.
Así, Mozilla asegura el soporte DOM de XML en todas las plataformas de todos los
navegadores basados en Gecko.
Para crear un DOM de XML en Firefox, debemos llamar al método createDocument ()
correspondiente al objeto document. implementation.
Este método acepta tres argumentos:
1. Una cadena que contiene el espacio de nombres URI para el documento que
se desea utilizar
2. Es una cadena que contiene el nombre cualificado del elemento raíz del
documento
3. El tipo de documento (también conocido como doctype) que deseamos crear.
Actualmente no hay soporte JavaScript para tipos de documentos en Firefox,
de forma que el tercer argumento debería ser siempre null.
Los nombres de los espacios de nombres XML pueden aparecer como nombres
cualificados, que contienen un símbolo de dos puntos (:) que divide al nombre en un
prefijo del espacio de nombres y una parte local. El prefijo, que corresponde a la
referencia URI, selecciona un espacio de nombres. La combinación del espacio de
nombres URI gestionado universalmente y del espacio de nombres propio del
documento produce identificadores que son únicos a nivel universal. Se proporcionan
mecanismos para definir el ámbito de los prefijos y los valores por defecto.
Para crear un documento DOM vacío, podemos hacer lo siguiente:
var oXmlDom = document.implementation.createDocument(“”,””,null);
Para crear un DOM de XML con un elemento de documento, especifique el nombre de
la etiqueta en el segundo argumento:
var oXmlDom = document.implementation.createDocument(“”,”libros”,null);
Este código crea un DOM de XML cuyo documentElement es <libros/>.
6
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
Especificando el espacio de nombres URI en el primer argumento:
var oXmlDom = document.implementation.createDocument ("http://www.site.com",
"libros",
null)
Cuando especificamos un espacio de nombres en el método createDocument (),
Firefox asígna automáticamente el prefijo 0 para representar el espacio de nombres
URL <a0:libros xmlns:a0="http: //www.site.com" />
5.- XML en plataformas cruzadas
(http://www.w3schools.com/dom/dom_parser.asp)
Siempre es necesario tener en cuenta las diferencias del código Javascript entre las
plataformas cruzadas.
Para ello diseñamos esta función de Javascript.
<html>
<head>
<script type="text/javascript">
var xmlDoc;
var navegador;
function cargaDocumento() {
// code for IE
if (window.ActiveXObject){
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
navegador = “IE”;
consola("IE")
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation &&
document.implementation.createDocument) {
xmlDoc=document.implementation.createDocument("","",null);
navegador = “FI”;
consola("Mozilla, Firefox u Opera")
// Error
} else {
consola("Este navegador no soporta DOM");
}
consola(xmlDoc);
}
function consola(txt){
var con = document.getElementById("consola");
con.innerHTML += txt + "<br> ";
}
</script>
</head>
<body onLoad="cargaDocumento()">
<div id="consola"></div>
</body>
</html>
7
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
En este ejemplo aparecerá en la consola el navegador que estamos usando. En caso
de que el navegador soporte ActiveXObject escribirá IE, en caso de que soporte
document.implementation y este permita crear documentos estamos ante Firefox y en
caso de que no lo soporte entonces pintará un error.
Aprovechamos para guardar en la variable “navegador” de que navegador se trata.
6.- Carga de un documento XML (o html)
Ambos navegadores soportan el método de cargar XML con load() que se puede
combinar con el método ASYNC.
LOAD() Æ Permite cargar una un archivo XML en una localización específica en la
Web.
ASYNC Æ Como sucede con XMLHttp (AJAX), load () nos permite cargar los datos en
dos modos: asíncrono y sincrónico. Por defecto, el método load () es asíncrono. Para
utilizar el modo sincrónico, debemos configurar async del objeto MSXML como false.
function cargaXML(dir){
cargaDocumento();
xmlDoc.async = false;
try {xmlDoc.load(dir);}
catch (oError) {consola(oError.description + oError);return false; }
var raiz = xmlDoc.documentElement;
consola(texto(raiz))
}
Creamos esta función que intenta cargar la dirección indicada. Si falla capturamos el
error y lo mostramos en la consola. Si no falla mostramos lo que vale xmlDoc.
Para mostrar el contenido del XML cargado hemos recurrido a una función que recorre
todo el árbol XML y que recoge cada valor de cada nodo con el fin de que sea
compatible en ambos navegadores. Adelantándonos en el tema (luego se explica
cada método) usaremos este visor de contenido de lo que cargamos:
function texto(oNodo){
var tt = "";
for (var i=0; i<oNodo.childNodes.length; i++){
if(oNodo.childNodes[i].hasChildNodes()) {
tt += texto(oNodo.childNodes[i])
}
else {tt += oNodo.childNodes[i].nodeValue;}
}
return tt;
}
EJERCICIOS:
¿Qué ocurre si probamos un XML local?
1.- En Firefox
2.- En iExplorer
8
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
<platos>
<primeros>
<nombre>Macarrones</nombre>
<fecha>Sun, 30 Dec 1899 00:00:00 +0100</fecha>
</primeros>
<primeros>
<nombre>Paella</nombre>
<fecha>Fri, 30 Dec 2004 00:00:00 +0100</fecha>
</primeros>
</platos>
<body onLoad="cargaXML(‘carga_xml.xml’)";>
¿Qué ocurre si probamos un RSS (que es XML) de un dominio externo al que
cargamos esta función?
<body onLoad="cargaXML('http://www.boua.ua.es/rss.asp')";>
3.- Prueba desde un dominio (127.0.0.1) ¿qué ocurre con Firefox? ¿Qué ocurre
con iExplorer?
4.- Prueba desde una dirección de disco (G:\curso_dom_ajax_xml\
tema3\ejercicios\carga_xml.html) ¿qué ocurre con Firefox? ¿y con iExplorer?
5.- ¿Qué ocurre si probamos con un XML mal formado / no válido?
<platos>
<primeros>
<nombre>Macarrones</nombre>
<fecha>Sun, 30 Dec 1899 00:00:00 +0100</fecha>
</primeros>
<primeros>
<nombre>Paella</nombre>
<fecha>Fri, 30 Dec 2004 00:00:00 +0100</fecha>
</primeros>
</kk>
Cuando trabajamos en modo asíncrono ASYNC= true entonces el script continua
aunque el XML no se haya cargado (igual que ocurre con AJAX). Para controlar si se
ha terminado de cargar necesitamos el evento de onreadystatechange que permite
monotorizar la propiedad readyState. Por desgracia es solo de Explorer. El Firefox
usa el evento Load y el manejador de envento onload.
Cruzando ambos navegadores saldría:
9
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
function cargaXML(dir){
cargaDocumento();
xmlDoc.async = true;
xmlDoc.load(dir);
if (navegador==”IE”){
xmlDoc.onreadystatechange = function(){
if (xmlDoc.readyState == 4){
var raiz = xmlDoc.documentElement;
consola(texto(raiz));
}else {
consola(xmlDoc.readyState + " sentado esperado");
};
}
}else{
xmlDoc.onload = function(){
var raiz = xmlDoc.documentElement;
consola(texto(raiz));
}
}
}
Lo cual es un lío: mientras que iExplorer si espera a que se cargue la página (gracias a
readyState que se me te en un bucle igual que hacía AJAX), Gecko no. Es por eso que
evitaremos usar el DOM de esta manera.
Concretamente, en este ejemplo, en la parte que se refiere a Explorer:
xmlDoc.onreadystatechange = function(){
if (xmlDoc.readyState == 4){
var raiz = xmlDoc.documentElement;
consola(texto(raiz));
}else {
consola(xmlDoc.readyState + "sentado esperado");
};
}
El documento XML que se indica en la variable dir (por ejemplo “rss.xml”) se carga en
el DOM de XML. Cuando readyState alcanza el valor 4, significa que el documento se
ha cargado por completo y se ejecuta el código que se encuentra dentro del bloque if.
LOADXML (loadXML) Æ solo iExplorer
La segunda forma de cargar datos XML, loadXML (), difiere del método load () en que
se carga XML desde una cadena. Esta cadena debe contener código XML bien
formado, como en el siguiente ejemplo:
var sXml = "<root><persona><nombre>Pepe Pepe Oreja
Repe</nombre></persona></root>";
XmlDoc.loadXML(sXml);
Aquí, los datos XML contenidos en la variable sXml se cargan en el documento
XmlDoc. No hay ninguna razón para comprobar la propiedad readyState o para
configurar la propiedad async cuando empleamos loadXML(), ya que no implica
ninguna petición al servidor.
El método loadXML () no existe en la implementación en Firefox. Sin embargo, es
posible emular su comportamiento mediante la clase DOMParser. DOMParser dispone
de un método llamado parseFromString (), que carga una cadena y la inicializa en un
documento:
10
Curso AJAX Y DOM 2007
Marcos A. San Martín Calera
Septiembre 2007
var oParser = new DOMParser();
xmlDoc = oParser.parseFromString(txt,"text/xml");
El método parseFromString () devuelve un objeto DOM de XML, de forma que
podemos tratar XmlDoc en este código como uno de estos objetos.
El código cruzado quedaría:
function cargaTxtXML(){
cargaDocumento();
if(navegador=="IE") xmlDoc.loadXML(txt);
else {
var oParser = new DOMParser();
xmlDoc = oParser.parseFromString(txt,"text/xml");
}
var raiz = xmlDoc.documentElement;
consola(texto(raiz));
};
11
Descargar