Prácticas

Para las siguientes prácticas se indicarán los siguientes puntos a desarrollar por cada una:

  • Cada práctica contará con su propio directorio ráiz: $HOME/www/dom0x
  • Cada práctica contará con un nombre de host: dom0x.com
  • Cada práctica contará con un puerto TCP: 808x
  • En base al nombre de host se tendrá un URL: http://dom0x.com:808x
  • El servidor web a usar es thttpd:

     alumno@servidor:~ $ cd $HOME/www/dom0x
     alumno@servidor:~ $ thttpd -D -p 808x -nor -T UTF-8 -l -
    

Práctica 01

  • Directorio ráiz: $HOME/www/dom01.
  • Puerto TCP: 8081
  • Nombre de host: dom01.com
  • URL: http://dom01.com:8081

Esta práctica plantea la inclusión de JavaScript (embebido) en un documento HTML así como su inclusión desde un archivo externo al documento HTML. Por otro lado se plantea el problema del entorno global para la ejecución correcta de un programa en JavaScript.

  1. Crea el archivo index.html con el siguiente contenido:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>dom01.com</title>
        <script src="js/dom01a.js"></script>
        <script src="js/dom01b.js"></script>
        <script>
          var x = 10;
          console.log("Se ha definido la variable: x");
          var y = 20;
          console.log("Se ha definido la variable: y");
        </script>
      </head>
      <body>
        <h1>dom01.com</h1>
      </body>
    </html>
    
  2. Crea el directorio js y en él el archivo dom01a.js con el siguiente contenido:

    var pares = [12, 14, 16, 18];
    console.log("Se ha definido la variable pares.");
    
  3. Crea el el archivo js/dom01b.js con el siguiente contenido:

    var decrementar_a_cada_uno = function(arr_numeros) {
      for (var i = 0; i < arr_numeros.length; i++) {
        arr_numeros[i] = arr_numeros[i] - 1;
      }
      return arr_numeros;
    }
    console.log("Se ha definido la variable: decrementar_a_cada_uno");
    
  4. Accede a http://dom01.com:8081, inicia la Consola de JavaScript (Firebug) y recarga la página con el juego de teclas Ctrl + F5.

  5. Ejecuta en la Consola de JavaScript lo siguiente, uno por uno:

    console.log(x); ↵
    console.log(y); ↵
    console.log(window.x); ↵
    console.log(window.y); ↵
    console.log(x + y); ↵
    console.log(window.x + window.y); ↵
    
    for (var i = 0; i < pares.length; i++) {
      console.log(pares[i]);
    } ↵
    
    window.y = window.x + pares[3]; ↵
    console.log(y); ↵
    console.log(window.y); ↵
    

Observaciones:

  • El código de JavaScript escrito entre la etiqueta <script> y el encontrado en los archivos js/dom01a.js y js/dom01b.js ha sido ejecutado. Pregunta: ¿en qué orden?.
  • Las variables x, y, y pares se encuentran a tu alcance. Pregunta: ¿tiene importancia el orden de ejecución?.

Ahora realiza lo siguiente:

  1. Mueve el elemento <script src="js/dom01b.js"></script> una línea antes de </body>:

     <body>
       <h1>dom01.com</h1>
       <script src="js/dom01b.js"></script>
     </body>
    
  2. Agrega lo siguiente al final de js/dom01b.js:

     var x = "Hola"; ↵
     console.log("Se ha definido la variable: x"); ↵
     var y = "mundo!"; ↵
     console.log("Se ha definido la variable: y"); ↵
    
  3. Recarga la página con el juego de teclas Ctrl + F5 y en la Consola de JavaScript ejecuta, uno por uno:

     console.log(x); ↵
     console.log(y); ↵
     console.log(window.x); ↵
     console.log(window.y); ↵
     console.log(x + y); ↵
     window.y = window.x + pares[3]; ↵
    
     console.log(pares); ↵
     var pares_decrementados = decrementar_a_cada_uno(pares); ↵
     console.log(pares_decrementados); ↵
     console.log(pares); ↵
    

Observaciones:

  • Se presento una redefinición de las variables x e y. El resultado puede no ser el esperado.
  • La función pares_decrementados tiene acceso a la variable global pares. De igual forma, el resultado puede no ser el esperado.

Conclusiones:

La definición descuidada de variables, el dinámismo (alteración) de los objetos/arreglos y una programación basada en la semántica de otros lenguajes hace que la programación en JavaScript sea propensa a errores.

Para mejorar la situación se recomienda hacer uso del patrón de diseño Módulo.

Lecturas

Práctica 02

  • Directorio ráiz: $HOME/www/dom02.
  • Puerto TCP: 8082
  • Nombre de host: dom02.com
  • URL: http://dom02.com:8082

Esta práctica plantea el uso de algunas propiedades en el entorno global (u objeto global) window, relacionado con el DOM (Document Object Model) y el BOM (Browser Object Model).

  1. Crea el archivo index.html con el siguiente contenido:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>dom02.com</title>
      </head>
      <body>
        <h1>dom02.com</h1>
        <hr>
          <a href="2010">2010</a>
          <a href="2011">2011</a>
        <hr>
        <script src="js/dom02a.js"></script>
      </body>
    </html>
    
  2. Crea los siguientes directorios: 2010/enero/01 y 2011/enero/01:

    alumno@servidor:~ $ cd $HOME/www/dom02/
    alumno@servidor:~/www/dom02 $ mkdir -p 2010/enero/01 2011/enero/01
    
  3. Crea los siguientes archivos:

    • 2010/index.html:

       <!DOCTYPE html>
       <html>
         <head>
           <meta charset="UTF-8">
           <title>dom02.com / 2010</title>
         </head>
         <body>
           <h1>2010</h1>
           <hr>
             <a href="../">Regresar</a>
             <a href="enero">enero</a>
           <hr>
           <script src="../js/dom02a.js"></script>
         </body>
       </html>
      
    • 2010/enero/index.html:

       <!DOCTYPE html>
       <html>
         <head>
           <meta charset="UTF-8">
           <title>dom02.com / 2010 / enero</title>
         </head>
         <body>
           <h1>2010 > enero</h1>
           <hr>
             <a href="../">Regresar</a>
             <a href="01">01</a>
           <hr>
           <script src="../../js/dom02a.js"></script>
         </body>
       </html>
      
    • 2010/enero/01/index.html:

       <!DOCTYPE html>
       <html>
         <head>
           <meta charset="UTF-8">
           <title>dom02.com / 2010 / enero / 01</title>
         </head>
         <body>
           <h1>2010 > enero > 01</h1>
           <hr>
             <a href="../">Regresar</a>
           <hr>
           <script src="../../../js/dom02a.js"></script>
         </body>
       </html>
      
  4. Nota: crea los anteriores documentos HTML dentro de los directorios existente en 2011, modificando lo pertinente para reflejar su ubicación (elementos <title> y <h1>).

  5. Crea el directorio js y en él el archivo dom02a.js con el siguiente contenido:

    var dom02a = (function() {
      var _localizacion = function() {
        /*
         * Algunas propiedades del objeto window.location:
         *   host
         *   hostname
         *   href
         *   pathname
         *   port
         *   assign()
         *   reload()
         * Documentación:
         *   https://developer.mozilla.org/en/docs/Web/API/Location
         */
        return window.location;
      };
    
      var _historial = function() {
        /*
         * Algunas propiedades del objeto window.history:
         *   back()
         *   forward()
         * Documentación:
         *   https://developer.mozilla.org/en/docs/Web/API/History
         */
        return window.history;
      };
    
      var _navegador = function() {
        /*
         * Algunas propiedades del objeto window.navigator:
         *   userAgent
         *   language
         *   languages
         *   onLine
         *   oscpu
         * Documentación:
         *   https://developer.mozilla.org/en/docs/Web/API/Navigator
         */
        return window.navigator;
      };
    
      var _alertar_al_usuario = function(mensaje) {
        /*
         * Documentación:
         *   https://developer.mozilla.org/en/docs/Web/API/Window/alert
         */
        if (typeof mensaje !== "string") {
          window.alert("");
        } else {
          window.alert(mensaje);
        }
      };
    
      var _solicitar_confirmacion_al_usuario = function(mensaje) {
        /*
         * Documentación:
         *   https://developer.mozilla.org/en/docs/Web/API/Window/confirm
         */
        if (typeof mensaje !== "string") {
          return window.confirm("");
        }
        return window.confirm(mensaje);
      };
    
      var _solicitar_valor_al_usuario = function(mensaje, por_default) {
        /*
         * Documentación:
         *   https://developer.mozilla.org/en/docs/Web/API/Window/prompt
         */
        var _mensaje = mensaje;
        var _por_default = por_default;
        if (typeof mensaje !== "string") {
          _mensaje = "";
        }
        if (typeof por_default !== "string") {
          _por_default = "";
        }
        return window.prompt(_mensaje, _por_default);
      };
    
      var _imprimir_documento = function() {
        /*
         * Documentación:
         *   https://developer.mozilla.org/en/docs/Web/API/Window/print
         */
        window.print();
      };
    
      var _consola = function() {
        /* Algunas propiedades del objeto window.console:
         *   dir()
         *   error()
         *   group() / groupEnd()
         *   info()
         *   log()
         *   table()
         *   time() / timeEnd()
         *   timeStamp()
         *   warn()
         * Documentación:
         *   https://developer.mozilla.org/en/docs/Web/API/Console
         */
        return window.console;
      };
    
      var _documento = function() {
        /*
         * Algunas propiedades del objeto window.document:
         *   characterSet
         *   doctype
         *   documentURI
         *   body
         *   domain
         *   location
         *   scripts
         *   title
         *   URL
         *   write()
         * Documentación:
         *   https://developer.mozilla.org/en/docs/Web/API/Window/document
         *   https://developer.mozilla.org/en/docs/Web/API/document
         */
        return window.document;
      };
    
      return {
        "localizacion": _localizacion,
        "historial": _historial,
        "navegador": _navegador,
        "alertar_al_usuario": _alertar_al_usuario,
        "solicitar_confirmacion_al_usuario": _solicitar_confirmacion_al_usuario,
        "solicitar_valor_al_usuario": _solicitar_valor_al_usuario,
        "imprimir_documento": _imprimir_documento,
        "consola": _consola,
        "documento": _documento
      };
    })();
    
  6. Accede a http://dom02.com:8082, inicia la Consola de JavaScript y recarga la página con el juego de teclas Ctrl + F5.

Nota: al terminar los anteriores pasos tendrás la siguiente estructura:

alumno@servidor:~/www/dom02 $ pwd && tree
/home/alumno/www/dom02
.
├── 2010
│   ├── enero
│   │   ├── 01
│   │   │   └── index.html
│   │   └── index.html
│   └── index.html
├── 2011
│   ├── enero
│   │   ├── 01
│   │   │   └── index.html
│   │   └── index.html
│   └── index.html
├── index.html
└── js
    └── dom02a.js

7 directories, 8 files

Ahora realiza lo siguiente:

  1. Ejecuta en la Consola de JavaScript lo siguiente, uno por uno:

    Importante: presta mucha atención a lo impreso en la Consola de JavaScript durante la realización de esta práctica.

    • Sobre window.location.

      Te permitirá obtener información sobre la barra de direcciones:

       dom02a.localizacion().hostname; ↵
       dom02a.localizacion().port; ↵
       dom02a.localizacion().pathname; ↵
       dom02a.localizacion().reload(); ↵
       dom02a.localizacion().assign("http://hernandezblasantonio.bitbucket.org"); ↵
      
    • Sobre window.history:

      Te permitirá regresar o avanzar en el historial de navegación del usuario, navega entre los enlaces disponibles en los archivos index.html para observar su efecto:

       dom02a.historial().back(); ↵
       dom02a.historial().forward(); ↵
      
    • Sobre window.navigator:

      Te permitirá obtener información sobre el navegador web:

       dom02a.navegador().userAgent; ↵
       dom02a.navegador().language; ↵
       dom02a.navegador().languages; ↵
       dom02a.navegador().oscpu; ↵
      
    • Sobre window.alert:

      Te permitirá mostrar un mensaje de alerta como Ventana modal al usuario:

       dom02a.alertar_al_usuario("¡Hey Usuario! !Alertate!"); ↵
      
    • Sobre window.confirm:

      Te permitirá mostrar un mensaje de confirmación como Ventana modal al usuario:

       var confirmacion = dom02a.solicitar_confirmacion_al_usuario("¿Confirmado?"); ↵
       typeof confirmacion; ↵
      
    • Sobre window.prompt:

      Te permitirá solicitar un valor, mostrando un mensaje de solicitud como Ventana modal al usuario:

       var valor_ingresado = dom02a.solicitar_valor_al_usuario("Dame un valor"); ↵
       typeof valor_ingresado; ↵
      
    • Sobre window.print:

      Te permitirá solicitar al navegador web la impresión del documento HTML:

       dom02a.imprimir_documento(); ↵
      
    • Sobre window.console:

      Te permitirá conocer un poco mejor al objeto console (comunmente usado console.log()):

       dom02a.consola().log("¡Hola mundo!"); ↵
       dom02a.consola().info("¡Esto es un mensaje de información!"); ↵
       dom02a.consola().error("¡Esto es un mensaje de error!"); ↵
       dom02a.consola().warn("¡Esto es un mensaje de advertencia!"); ↵
      
       dom02a.consola().group(); ↵
       dom02a.consola().log("Estos"); ↵
       dom02a.consola().log("son varios"); ↵
       dom02a.consola().log("mensajes agrupados"); ↵
       dom02a.consola().groupEnd(); ↵
      
       dom02a.consola().group(); ↵
       dom02a.consola().warn("Y estos"); ↵
       dom02a.consola().warn("son varios"); ↵
       dom02a.consola().warn("mensajes de advertencia agrupados"); ↵
       dom02a.consola().groupEnd(); ↵
      
       dom02a.consola().group(); ↵
         dom02a.consola().info("Es posible agrupar y anidar los mensajes."); ↵
           dom02a.consola().group(); ↵
             dom02a.consola().warn("Por ejemplo, este es un mensaje de advertencia"); ↵
             dom02a.consola().warn("dentro de unos mensajes de información"); ↵
           dom02a.consola().groupEnd(); ↵
         dom02a.consola().info("los cuales terminan aquí."); ↵
       dom02a.consola().groupEnd(); ↵
      
       var obj1 = {"x": 10, "y": 20, "z": 30}; ↵
       dom02a.consola().table(obj1); ↵
       var obj2 = {"x": 10, "y": [15, 20, 25], "z": 30}; ↵
       dom02a.consola().table(obj2); ↵
       var obj3 = {"x": 10, "y": {"a": 15, "b": 20, "c": 25}, "z": 30}; ↵
       dom02a.consola().table(obj3); ↵
      
       var arr1 = [10, 20, 30]; ↵
       dom02a.consola().table(arr1); ↵
       var arr2 = [10, {"a": 15, "b": 20, "c": 25}, 30]; ↵
       dom02a.consola().table(arr2); ↵
      
       dom02a.consola().time("tiempo-de-ciclo-for"); ↵
       for (var i = 0, total = 0; i <= 999999; i++ ) {
         total = total + i;
       } ↵
       dom02a.consola().timeEnd("tiempo-de-ciclo-for"); ↵
       dom02a.consola().info("Resultado total: " + total); ↵
      
  2. Sobre window.document:

    Te permitirá acceder a información propia del documento HTML en el que te encuentres:

        dom02a.documento().characterSet; ↵
        dom02a.documento().doctype; ↵
        dom02a.documento().documentURI; ↵
        dom02a.documento().domain; ↵
        dom02a.documento().location; ↵
        dom02a.documento().scripts; ↵
        dom02a.documento().title; ↵
        dom02a.documento().title = "HOLA MUNDO"; ↵
        dom02a.documento().title; ↵
    

Observaciones:

  • El objeto global window se encuentra disponible al módulo dom02a.
  • El uso de las propiedades alert, confirm y prompt del objeto global window en la actualidad está desaconsejado debido a que:

    1. Son funciones que bloquean la ejecución continua del navegador web.
    2. Se han convertido en un problema de usabilidad para sitios/aplicaciones web.

    Dicho lo anterior, aún así es bueno conocer de su existencia.

  • La instrucción console.log(mensaje), comunmente usada en JavaScript, es en realidad window.console.log(mensaje). Puedes evaluar lo siguiente en la Consola de JavaScript:

     window.console === console
    

    En otras palabras, son el mismo objeto.

  • La instrucción document.title (con la cual puedes obtener el texto dentro del elemento <title> del documento HTML) es en realidad window.document.title. Puedes evaluar lo siguiente en la Consola de JavaScript:

     window.document === document
    

    En otras palabras, son el mismo objeto.

Conclusiones:

  • El DOM es algo que existe por el solo hecho de haber descargado un documento HTML, uno no tiene que hacer algo más para que los objetos window y document existán.
  • Mediante el DOM podemos obtener algunos datos sobre el documento HTML así como del navegador web.
  • El DOM no forma parte de JavaScript, son dos tecnológias separadas una de la otra. Por cuestiones del uso de JavaScript en el navegador web se suelen confundir, de está forma se puede tener problemas al momento de programar con JavaScript debido a que realmente se tienen problemas con el DOM.

Lecturas

Práctica 03

  • Directorio ráiz: $HOME/www/dom03.
  • Puerto TCP: 8083
  • Nombre de host: dom03.com
  • URL: http://dom03.com:8083

Esta práctica plantea el acceso a los elementos de un documento HTML haciendo uso del DOM.

  1. Crea el archivo index.html con el siguiente contenido:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>dom03.com</title>
      </head>
      <body>
        <h1>dom03.com</h1>
        <hr>
        <h2 class="dom-ingles">Document Object Model</h2>
        <hr>
        <p>
          <strong class="dom-ingles">Document Object Model</strong> o <strong>DOM</strong> (<em>'Modelo de Objetos del Documento'</em>
          o <em>'Modelo en Objetos para la Representación de Documentos'</em>) es esencialmente una interfaz de
          plataforma que proporciona un conjunto estándar de objetos para representar documentos HTML, XHTML y XML
        </p>
        <p id="un-modelo">
          Un modelo estándar sobre cómo pueden combinarse dichos objetos, y una interfaz estándar para acceder a
          ellos y manipularlos.
        </p>
        <p>
          A través del <em class="dom-ingles">Document Object Model</em>, los <em>programas pueden acceder y modificar el contenido,
          estructura y estilo de los documentos HTML</em> y XML, que es para lo que se diseñó principalmente.
        </p>
        <img src="img/dom.png">
        <ul>
          <li id="el-responsable">
            El responsable del DOM es el
            <a href="https://es.wikipedia.org/wiki/World_Wide_Web_Consortium">World Wide Web Consortium (W3C)</a>.
          </li>
          <li>
            El DOM permite el acceso dinámico a través de la programación para acceder, añadir y cambiar dinámicamente
            contenido estructurado en documentos con lenguajes como ECMAScript (JavaScript).
          </li>
        </ul>
        <hr>
        <h2>Índice</h2>
        <ol>
          <li>Estableciendo referencias a objetos</li>
          <li>Manipulando las propiedades y funciones de objetos</li>
          <li>Eventos</li>
          <li>Referencias</li>
          <li class="dom-ingles">Document Object Model</li>
        </ol>
        <em>
          Fuente:
          <a href="https://es.wikipedia.org/wiki/Document_Object_Model">Wikipedia</a>
        </em>
        <hr>
        <table>
          <thead>
            <tr><th>A</th><th>B</th><th>C</th><th>D</th></tr>
          </thead>
          <tbody>
            <tr><td> 2</td><td>10</td><td>18</td><td name="columna-d">26</td></tr>
            <tr><td>4 </td><td>12</td><td>20</td><td name="columna-d">28</td></tr>
            <tr><td> 6</td><td>14</td><td>22</td><td name="columna-d">30</td></tr>
            <tr><td>8 </td><td>16</td><td>24</td><td name="columna-d">32</td></tr>
          </tbody>
        </table>
        <script src="js/dom03a.js"></script>
      </body>
    </html>
    
  2. Crea el directorio js y en él el archivo dom03a.js con el siguiente contenido:

    var dom03a = (function() {
      var _elemento_con_id = function(id_del_elemento) {
        return document.getElementById(id_del_elemento);
      };
    
      var _imprimir_texto_de_elemento_con_id = function(id_del_elemento) {
        console.log(_elemento_con_id(id_del_elemento).textContent);
        console.log("-------------");
      };
    
      var _elementos_con_clase = function (clase_de_los_elementos) {
          return document.getElementsByClassName(clase_de_los_elementos);
      }
    
      var _imprimir_texto_de_elementos_con_clase = function(clase_de_los_elementos) {
        for (var i = 0; i < _elementos_con_clase(clase_de_los_elementos).length; i++) {
          console.log(_elementos_con_clase(clase_de_los_elementos)[i].textContent);
          console.log("-------------");
        }
      };
    
      var _elementos_con_nombre = function (nombre_de_los_elementos) {
          return document.getElementsByName(nombre_de_los_elementos);
      }
    
      var _imprimir_texto_de_elementos_con_nombre = function(nombre_de_los_elementos) {
        for (var i = 0; i < _elementos_con_nombre(nombre_de_los_elementos).length; i++) {
          console.log(_elementos_con_nombre(nombre_de_los_elementos)[i].textContent);
          console.log("-------------");
        }
      };
    
      var _elementos_p = function () {
        return document.getElementsByTagName("p");
      };
    
      var _imprimir_texto_de_elementos_p = function() {
        for (var i = 0; i < _elementos_p().length; i++) {
          console.log("> Parrafo " + i);
          console.log(_elementos_p()[i].textContent);
          console.log("-------------");
        }
      };
    
      var _elementos_li = function() {
        return document.getElementsByTagName("li");
      };
    
      var _imprimir_texto_de_elementos_li = function() {
        for (var i = 0; i < _elementos_li().length; i++) {
          console.log("> Ítem " + i);
          console.log(_elementos_li()[i].textContent);
          console.log("-------------");
        } 
      };
    
      var _elementos_a = function() {
        return document.getElementsByTagName("a");
      };
    
      var _imprimir_texto_de_elementos_a = function() {
        for (var i = 0; i < _elementos_a().length; i++) {
          console.log("> Enlace " + i);
          console.log(_elementos_a()[i].textContent);
          console.log("-------------");
        } 
      };
    
      var _imprimir_valor_de_atributo_href_de_elementos_a = function() {
        for (var i = 0; i < _elementos_a().length; i++) {
          console.log("> Enlace " + i);
          console.log(_elementos_a()[i].getAttribute("href"));
          console.log("-------------");
        } 
      };
    
      var _elementos_td = function() {
        return document.getElementsByTagName("td");  
      };
    
      var _imprimir_texto_de_elementos_td = function() {
        for (var i = 0; i < _elementos_td().length; i++) {
          console.log("> Celda " + i + " : " + _elementos_td()[i].textContent);
          console.log("-------------");
        } 
      };
    
      var _concatenacion_del_texto_de_elementos_td = function() {
        var _str_salida = "";
        for (var i = 0; i < _elementos_td().length; i++) {
            _str_salida = _str_salida + _elementos_td()[i].textContent;
        }
        return _str_salida;
      };
    
      var _elementos_th = function() {
        return document.getElementsByTagName("th");  
      };
    
      var _imprimir_texto_de_elementos_th = function() {
        for (var i = 0; i < _elementos_th().length; i++) {
          console.log("> Cabecera " + i + " : " + _elementos_th()[i].textContent);
          console.log("-------------");
        } 
      };
    
      var _elementos_img = function() {
        return document.getElementsByTagName("img");
      };
    
      var _imprimir_valor_de_atributo_src_de_elementos_img = function() {
        for (var i = 0; i < _elementos_img().length; i++) {
          console.log("> Imagen " + i);
          console.log(_elementos_img()[i].getAttribute("src"));
          console.log("-------------");
        } 
      };
    
      return {
        "elemento_con_id": _elemento_con_id,
        "imprimir_texto_de_elemento_con_id": _imprimir_texto_de_elemento_con_id,
        "elementos_con_clase": _elementos_con_clase,
        "imprimir_texto_de_elementos_con_clase": _imprimir_texto_de_elementos_con_clase,
        "elementos_con_nombre": _elementos_con_nombre,
        "imprimir_texto_de_elementos_con_nombre": _imprimir_texto_de_elementos_con_nombre,
        "elementos_p": _elementos_p,
        "imprimir_texto_de_elementos_p": _imprimir_texto_de_elementos_p,
        "elementos_li": _elementos_li,
        "imprimir_texto_de_elementos_li": _imprimir_texto_de_elementos_li,
        "elementos_a": _elementos_a,
        "imprimir_texto_de_elementos_a": _imprimir_texto_de_elementos_a,
        "imprimir_valor_de_atributo_href_de_elementos_a": _imprimir_valor_de_atributo_href_de_elementos_a,
        "elementos_td": _elementos_td,
        "imprimir_texto_de_elementos_td": _imprimir_texto_de_elementos_td,
        "concatenacion_del_texto_de_elementos_td": _concatenacion_del_texto_de_elementos_td,
        "elementos_th": _elementos_th,
        "imprimir_texto_de_elementos_th": _imprimir_texto_de_elementos_th,
        "elementos_img": _elementos_img,
        "imprimir_valor_de_atributo_src_de_elementos_img": _imprimir_valor_de_atributo_src_de_elementos_img
      };
    })();
    
  3. Crea el directorio img y descarga una imagen (dom.png) en él ejecutando el siguiente comando:

    alumno@servidor:~/www/dom03 $ wget -c \
      'https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/DocumentObjectModelES.svg/180px-DocumentObjectModelES.svg.png' \
      -O img/dom.png
    
  4. Accede a http://dom03.com:8083, inicia la Consola de JavaScript y recarga la página con el juego de teclas Ctrl + F5.

    • Obtener una referencia a un elemento del documento HTML en base a su atributo id:

       dom03a.elemento_con_id("un-modelo"); ↵
      
    • Obtener una colección (arreglo) de elementos HTML (sus referencias) en base a su etiqueta:

       dom03a.elementos_p(); ↵
       dom03a.elementos_a(); ↵
       dom03a.elementos_li(); ↵
       dom03a.elementos_td(); ↵
       dom03a.elementos_th(); ↵
       dom03a.elementos_img(); ↵
      
    • Obtener una colección (arreglo) de elementos HTML (sus referencias) en base a su atributo class:

       dom03a.elementos_con_clase("dom-ingles"); ↵
      
    • Obtener una colección (arreglo) de elementos HTML (sus referencias) en base a su atributo name:

       dom03a.elementos_con_nombre("columna-d"); ↵
      
    • Acceder a algún atributo de algún elemento HTML:

       dom03a.imprimir_valor_de_atributo_href_de_elementos_a(); ↵
       dom03a.imprimir_valor_de_atributo_src_de_elementos_img(); ↵
      
    • Acceder (imprimir o concatenar) el texto entre las etiquetas de algún elemento HTML:

       dom03a.imprimir_texto_de_elementos_p(); ↵
       dom03a.imprimir_texto_de_elementos_li(); ↵
       dom03a.imprimir_texto_de_elementos_a(); ↵
       dom03a.imprimir_texto_de_elemento_con_id("un-modelo"); ↵
       dom03a.imprimir_texto_de_elementos_th(); ↵
       dom03a.imprimir_texto_de_elementos_con_clase("dom-ingles"); ↵
       dom03a.imprimir_texto_de_elementos_con_nombre("columna-d"); ↵
       dom03a.imprimir_texto_de_elementos_td(); ↵
       dom03a.concatenacion_del_texto_de_elementos_td(); ↵
      

Conclusiones:

  • El DOM nos permite ver a los elementos del documento HTML como objectos en JavaScript, acceder a sus atributos-propiedades y modificarlos.

Lecturas

Práctica 04

  • Directorio ráiz: $HOME/www/dom04.
  • Puerto TCP: 8084
  • Nombre de host: dom04.com
  • URL: http://dom04.com:8084

Esta práctica plantea la modificación del estilo de los elementos en un documento HTML mediante el uso del DOM y JavaScript. Para lo anterior se integrará el toolkit de Interfaz de Usuario PureCSS.

  1. Crea el archivo index.html con el siguiente contenido:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>dom04.com</title>
        <link rel="stylesheet" href="css/pure/pure-min.css">
        <!--[if lte IE 8]>
          <link rel="stylesheet" href="css/pure/grids-responsive-old-ie-min.css">
        <![endif]-->
        <!--[if gt IE 8]><!-->
          <link rel="stylesheet" href="css/pure/grids-responsive-min.css">
        <!--<![endif]-->
        <link rel="stylesheet" href="css/main.css">
      </head>
      <body>
        <h1>dom04.com</h1>
        <hr>
        <h2>Document Object Model</h2>
        <hr>
        <p>
          El <span id="el-dom">DOM</span> permite el acceso dinámico a través de la programación para acceder, añadir y
          cambiar dinámicamente contenido estructurado en documentos con lenguajes como
          <span id="ecmascript">ECMAScript</span> (<em class="js">JavaScript</em>).  
        </p>
        <p>
          Cualquier lenguaje de programación adecuado para el diseño web puede ser utilizado.
          En el caso de <strong class="js">JavaScript</strong>, cada objeto tiene un nombre,
          el cual es exclusivo y único. Cuando existen más de un objeto del mismo tipo en un
          documento web, estos se organizan en un vector.
        </p>
        <hr>
        <a href=".">Un enlace</a>
        <a href=".">Otro enlace</a>
        <a href=".">Otro enlace más</a>
        <a href=".">Último enlace</a>
        <hr>
        <table pure-table>
          <thead>
            <tr>
              <th>A</th><th>B</th><th>C</th><th>D</th>
            </tr>
          </thead>
          <tbody>
              <tr>
                <td>45</td><td>23</td><td>59</td><td>21</td>
              </tr>
              <tr>
                <td>11</td><td>98</td><td>66</td><td>43</td>
              </tr>
              <tr>
                <td>99</td><td>33</td><td>93</td><td>64</td>
              </tr>
              <tr>
                <td>65</td><td>64</td><td>22</td><td>12</td>
              </tr>
              <tr>
                <td>91</td><td>47</td><td>88</td><td>39</td>
              </tr>
          </tbody>
        </table> 
        <hr>
        <button class="pure-button pure-button-primary">Un botón</button>
        <button class="pure-button pure-button-primary">Otro botón</button>
        <button class="pure-button pure-button-primary">Otro botón más</button>
        <button class="pure-button pure-button-primary">Último botón</button>
        <script src="js/dom04a.js"></script>
      </body>
    </html>
    
  2. Crea el directorio css y descarga a PureCSS en él:

    alumno@servidor:~/www/dom04 $ mkdir -p css
    alumno@servidor:~/www/dom04 $ cd css
    alumno@servidor:~/www/dom04/css $ wget -c https://github.com/yahoo/pure-release/archive/v1.0.0.zip
    alumno@servidor:~/www/dom04/css $ unzip v1.0.0.zip
    alumno@servidor:~/www/dom04/css $ mv pure-release-1.0.0 pure
    
  3. Crea el archivo css/main.css con el siguiente contenido:

    .js {
      color: rgb(0, 0, 0);
    }
    
    #el-dom {
      font-size: 12px;
    }
    
  4. Crea el directorio js y crea el archivo dom04a.js con el siguiente contenido:

    var dom04a = (function() {
      var _ocultar_elemento_con_id = function(id_del_elemento) {
        var _elemento = document.getElementById(id_del_elemento);
        _elemento.setAttribute("hidden", "hidden");
      };
    
      var _mostrar_elemento_con_id = function(id_del_elemento) {
        var _elemento = document.getElementById(id_del_elemento);
        _elemento.removeAttribute("hidden");  
      };
    
      var _ocultar_elementos_con_clase = function(clase_de_los_elementos) {
        var _elementos = document.getElementsByClassName(clase_de_los_elementos);
        for (var i = 0; i < _elementos.length; i++) {
            _elementos[i].setAttribute("hidden", "hidden");
        }
      };
    
      var _mostrar_elementos_con_clase = function(clase_de_los_elementos) {
        var _elementos = document.getElementsByClassName(clase_de_los_elementos);
        for (var i = 0; i < _elementos.length; i++) {
            _elementos[i].removeAttribute("hidden");
        }
      };
    
      var _agrandar_el_texto_del_elemento_con_id = function(id_del_elemento) {
        var _elemento = document.getElementById(id_del_elemento);
        var _valor_de_font_size = window.getComputedStyle(_elemento).getPropertyValue("font-size");
        var _nuevo_tamanio = Number(_valor_de_font_size.split("px")[0]) + 5;
        _elemento.style.fontSize = _nuevo_tamanio + "px";
      };
    
      var _cambiar_el_color_de_los_elementos_con_clase = function(clase_de_los_elementos) {
        var _elementos = document.getElementsByClassName(clase_de_los_elementos);
        for (var i = 0; i < _elementos.length; i++) {
            var _valor_de_color = window.getComputedStyle(_elementos[i]).getPropertyValue("color");
            if (_valor_de_color === "rgb(0, 0, 0)") {
              _elementos[i].style.color = "rgb(255, 0, 0)";
            } else {
              _elementos[i].style.color = "rgb(0, 0, 0)";
            }
        }
      }
    
      var _estilizar_enlaces_como_botones_primarios = function() {
        var _elementos = document.getElementsByTagName("a");
        for (var i = 0; i < _elementos.length; i++) {
          _elementos[i].classList.add("pure-button");
          _elementos[i].classList.add("pure-button-primary");
        }
      };
    
      var _estilizar_con_default_una_tabla = function() {
        var _elementos = document.getElementsByTagName("table");
        for (var i = 0; i < _elementos.length; i++) {
          _elementos[i].classList.add("pure-table");
        }
      };
    
      var _estilizar_con_bordeado_una_tabla = function() {
        var _elementos = document.getElementsByTagName("table");
        for (var i = 0; i < _elementos.length; i++) {
          _elementos[i].classList.add("pure-table-bordered");
        }
      };
    
      var _estilizar_con_zebra_una_tabla = function() {
        var _elementos = document.getElementsByTagName("table");
        for (var i = 0; i < _elementos.length; i++) {
          _elementos[i].classList.add("pure-table-striped");
        }
      };
    
      var _desactivar_botones = function() {
        var _elementos = document.getElementsByTagName("button");
        for (var i = 0; i < _elementos.length; i++) {
          _elementos[i].classList.remove("pure-button-active");
          _elementos[i].classList.add("pure-button-disabled");
        }  
      };
    
      var _activar_botones = function() {
        var _elementos = document.getElementsByTagName("button");
        for (var i = 0; i < _elementos.length; i++) {
          _elementos[i].classList.remove("pure-button-disabled");
          _elementos[i].classList.add("pure-button-active");
        }  
      };
    
      return {
        "ocultar_elemento_con_id": _ocultar_elemento_con_id,
        "mostrar_elemento_con_id": _mostrar_elemento_con_id,
        "ocultar_elementos_con_clase": _ocultar_elementos_con_clase,
        "mostrar_elementos_con_clase": _mostrar_elementos_con_clase,
        "agrandar_el_texto_del_elemento_con_id": _agrandar_el_texto_del_elemento_con_id,
        "cambiar_el_color_de_los_elementos_con_clase": _cambiar_el_color_de_los_elementos_con_clase,
        "estilizar_enlaces_como_botones_primarios": _estilizar_enlaces_como_botones_primarios,
        "estilizar_con_default_una_tabla": _estilizar_con_default_una_tabla,
        "estilizar_con_bordeado_una_tabla": _estilizar_con_bordeado_una_tabla,
        "estilizar_con_zebra_una_tabla": _estilizar_con_zebra_una_tabla,
        "desactivar_botones": _desactivar_botones,
        "activar_botones": _activar_botones
      };
    })();
    

Al terminar obtendrás la siguiente estructura:

alumno@servidor:~/www/dom04 $ pwd && tree -L 2
/home/alumno/www/dom04
.
├── css
│   ├── main.css
│   ├── pure
│   └── v1.0.0.zip
├── index.html
└── js
    └── dom04a.js

3 directories, 4 files

Finalmente, realiza lo siguiente:

  1. Accede a http://dom04.com:8083, inicia la Consola de JavaScript y recarga la página con el juego de teclas Ctrl + F5.

  2. Ejecuta:

    • Para ocultar o mostrar un elemento del documento HTML en base a su atributo id:

       dom04a.ocultar_elemento_con_id("el-dom"); ↵
       dom04a.mostrar_elemento_con_id("el-dom"); ↵
      
    • Para ocultar o mostrar elementos del documento HTML en base a su atributo class:

       dom04a.ocultar_elementos_con_clase("js"); ↵
       dom04a.mostrar_elementos_con_clase("js"); ↵
      
    • Para modificar el CSS de algún elemento del documento HTML:

       dom04a.agrandar_el_texto_del_elemento_con_id("el-dom"); ↵
       dom04a.cambiar_el_color_de_los_elementos_con_clase("js"); ↵
      
    • Para agregar una clase a algún elemento del documento HTML:

       dom04a.estilizar_enlaces_como_botones_primarios(); ↵
      
    • Para agregar varias clases a algún elemento del documento HTML:

       dom04a.estilizar_con_default_una_tabla(); ↵
       dom04a.estilizar_con_bordeado_una_tabla(); ↵
       dom04a.estilizar_con_zebra_una_tabla(); ↵
      
    • Para remover y agregar una clase a algún elemento del documento HTML:

       dom04a.desactivar_botones(); ↵
       dom04a.activar_botones(); ↵
      

Lecturas

Práctica 05

  • Directorio ráiz: $HOME/www/dom05.
  • Puerto TCP: 8085
  • Nombre de host: dom05.com
  • URL: http://dom05.com:8085

Esta práctica plantea la programación de atención a eventos sobre los elementos en un documento HTML mediante el uso del DOM y JavaScript. Para lo anterior se integrará el toolkit de Interfaz de Usuario PureCSS.

  1. Crea el archivo index.html con el siguiente contenido:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>dom05.com</title>
        <link rel="stylesheet" href="css/pure/pure-min.css">
        <!--[if lte IE 8]>
          <link rel="stylesheet" href="css/pure/grids-responsive-old-ie-min.css">
        <![endif]-->
        <!--[if gt IE 8]><!-->
          <link rel="stylesheet" href="css/pure/grids-responsive-min.css">
        <!--<![endif]-->
        <link rel="stylesheet" href="css/main.css">
      </head>
      <body>
        <h1>dom05.com</h1>
        <hr>
        <h2>Eventos</h2>
        <hr>
          <h3>eventos01</h3>
          <form class="pure-form">
            <input type="text" id="numero" readonly="readonly" value="10" />
            <input type="button" id="incrementar" value="Incrementar" class="pure-button pure-button-primary">
            <input type="button" id="decrementar" value="Decrementar" class="pure-button pure-button-primary">
          </form>
        <hr>
        <hr>
          <h3>eventos02</h3>
          <textarea id="texto_original"></textarea>
          <p id="texto_copia"></p>
        </hr>
        <hr>
          <h3>eventos03</h3>
          <form class="pure-form">
            <input type="number" id="nuevo_elemento" min="100" max="990" step="10" value="100"/>
            <input type="button" id="agregar" value="Agregar" class="pure-button pure-button-primary">
          </form>
          <table class="pure-table">
            <tbody>  
              <tr id="cola">
                <th scope="row">Inicio</th>
                <td>NULL</td>
                <th scope="row">Fin</th>
              </tr>
            </tbody>
          </table>
        </hr>
        <hr>
          <h3>eventos04</h3>
          <form class="pure-form">
            <select id="mayusculas_o_minusculas">
              <option value="">Seleccione una opción</option>
              <option value="a_mayusculas">A mayúscula</option>
              <option value="a_minusculas">A minúscula</option>
            </select>
            <input type="email" name="correo" value="AAA" />
            <input type="email" name="correo" value="bbb" />
            <input type="email" name="correo" value="CCC" />
            <input type="email" name="correo" value="ddd" />
            <input type="email" name="correo" value="EeE" />
            <input type="email" name="correo" value="fFf" />
          </form>
        </hr>
        <script src="js/dom05a.js"></script>
      </body>
    </html>
    
  2. Crea el directorio css y descarga a PureCSS en él:

    alumno@servidor:~/www/dom05 $ mkdir -p css
    alumno@servidor:~/www/dom05 $ cd css
    alumno@servidor:~/www/dom05/css $ wget -c https://github.com/yahoo/pure-release/archive/v1.0.0.zip
    alumno@servidor:~/www/dom05/css $ unzip v1.0.0.zip
    alumno@servidor:~/www/dom05/css $ mv pure-release-1.0.0 pure
    
  3. Crea el archivo css/main.css, vácio.

  4. Crea el directorio js y crea el archivo dom05a.js con el siguiente contenido:

    var dom05a = (function() {
        var _stamp = function() {
            var obj_date = new Date();
            var _año = obj_date.getFullYear();
            var _mes = obj_date.getMonth();
            var _dia = obj_date.getDay();
            var _hora = obj_date.getHours();
            var _minuto = obj_date.getMinutes();
            var _segundo = obj_date.getSeconds();
            var _milisegundo = obj_date.getMilliseconds();
            return _año + "/"+_mes + "/" + _dia + " " + _hora + ":" + _minuto + ":" + _segundo + ":" + _milisegundo;
        };
        var _log = function(_sujeto, _arr_mensajes) {
            for (var i = 0; i < _arr_mensajes.length; i++) {
                console.info("[ " + _stamp() + " ] " + _sujeto + " : " + _arr_mensajes[i]);
            }
        };
        var _eventos01 = function() {
            _log("_eventos01()", ["Iniciando..."]);
            var incrementar = document.getElementById("incrementar");
            incrementar.addEventListener("click", function(obj_evento) {
                _log("click", ["elemento id='incrementar'"]);
                var numero = document.getElementById("numero");
                var cantidad = Number(numero.getAttribute("value"));
                numero.setAttribute("value", cantidad + 1);  
            }, false);
            var decrementar = document.getElementById("decrementar");
            decrementar.addEventListener("click", function(obj_evento) {
                _log("click", ["elemento id='decrementar'"]);
                var numero = document.getElementById("numero");
                var cantidad = Number(numero.getAttribute("value"));
                numero.setAttribute("value", cantidad - 1);  
            }, false);
            _log("_eventos01()", ["Terminando..."]);
        };
        var _eventos02 = function() {
            _log("_eventos02()", ["Iniciando..."]);
            var texto_original = document.getElementById("texto_original");
            texto_original.addEventListener("keypress", function(obj_evento) {
                _log("keypress", ["elemento id='texto_original'"]);
                var caracter = obj_evento.key;
                // var caracter = obj_evento.charCode;
                // var caracter = String.fromCharCode(obj_evento.charCode);
                var texto_copia = document.getElementById("texto_copia");
                texto_copia.textContent = texto_copia.textContent + caracter; 
            }, false);
            _log("_eventos02()", ["Terminando..."]);
        };
        var _eventos03 = function() {
            _log("_eventos03()", ["Iniciando..."]);
            var agregar = document.getElementById("agregar");
            agregar.addEventListener("click", function(obj_evento) {
                _log("click", ["elemento id='agregar'"]);
                var nuevo_elemento = document.getElementById("nuevo_elemento");
                var valor_numerico = Number(nuevo_elemento.value);
                var cola = document.getElementById("cola");
                var elementos = cola.children;
                var nuevo_td = document.createElement("td");
                nuevo_td.textContent = valor_numerico;
                cola.insertBefore(nuevo_td, elementos[(elementos.length - 2)]);
            }, false);
            _log("_eventos03()", ["Terminando..."]);
        };
        var _eventos04 = function() {
            _log("_eventos04()", ["Iniciando..."]);
            var mayusculas_o_minusculas = document.getElementById("mayusculas_o_minusculas");
            mayusculas_o_minusculas.addEventListener("change", function(obj_evento) {
                _log("change", ["elemento id='mayusculas_o_minusculas'"]);
                var opcion = obj_evento.originalTarget.value;
                var correos = document.getElementsByName("correo");
                if (opcion === "a_mayusculas") {
                    for (var i = 0; i < correos.length; i++) {
                        correos[i].value = correos[i].value.toUpperCase(); 
                    }
                }
                if (opcion === "a_minusculas") {
                    for (var i = 0; i < correos.length; i++) {
                        correos[i].value = correos[i].value.toLowerCase(); 
                    }
                }
            }, false);
            _log("_eventos04()", ["Terminando..."]);
        };
        var _main = function() {
            _log("_main()", ["Iniciando..."]);
            _eventos01();
            _eventos02();
            _eventos03();
            _eventos04();
            _log("_main()", ["Terminando..."]);
        };
        return {
            "main": _main
        };
    })();
    

Al terminar obtendrás la siguiente estructura:

alumno@servidor:~/www/dom04 $ pwd && tree -L 2
/home/alumno/www/dom05
.
├── css
│   ├── main.css
│   ├── pure
│   └── v1.0.0.zip
├── index.html
└── js
    └── dom05a.js

3 directories, 4 files

Finalmente, accede a http://dom05.com:8083, inicia la Consola de JavaScript, recarga la página con el juego de teclas Ctrl + F5, ejecuta dom05.main() e interactua con los elementos en el documento HTML.

Lecturas