sintesis

dhtml

Códigos disponibles en git

¿Por qué?

contexto

¿Qué?

Páginas Estáticas HTML Dinámico Páginas Dinámicas
  • Páginas HTML construidas en tiempo de compilación,

    • previo a la petición

  • DHTML es la abreviatura de Dynamic HTML, se refiere al código del que están hechas las páginas web interactivas: HTML + CSS + JavaScript

    • que se modifican conforme el usuario interactúa con ellas

  • Páginas HTML generadas tiempo de ejecución por parte del servidor tras consultar datos (sistema gestor de base de datos, servicios de información, …​) y construir la página HTML

    • posterior a la petición

¿Para qué?

  • Para dar "vida" (flujo de ejecución) a la presentación de la página HTML en el Navegador dinámicamente para mejorar la experiencia de usuario:

  • Usabilidad: despliega menúes, reacciona al cursor, teclas rápidas, …​

  • Eficiencia: evita peticiones al servidor con validación de los campos del formulario, …​

¿Cómo?

DOM y JavaScript

  • Lenguaje de guión, script, evaluando dentro del contexto del sistema: BOM y DOM

bomDomJavascript

Gestión de Nodos

Método write Ejemplo
  • Objeto [window.] document:

    • método write, redirige el flujo de caracteres de lectura del fichero HTML con el argumento dado de tipo string

      • Muy desaconsejado

<!DOCTYPE html>
<html>
<head>
  <title>JS DOM. write</title>
</head>
<body>
  <script>
    window.document.write("<h1>Título de write</h1>");
    document.write("<p>Párrafo</p>");
  </script>
</body>
</html>
Gestión de Elementos Ejemplo
<!DOCTYPE html>
<html>
<head>
  <title>JS DOM. element</title>
</head>
<body id="body"></body>
  <script>
    let bodyElement = document.getElementById("body");
    let titleElement = document.createElement("h1");
    let titleText = document.createTextNode("Título con element");
    titleElement.appendChild(titleText);
    bodyElement.appendChild(titleElement);
    let paragraphElement = document.createElement("p");
    let paragraphText = document.createTextNode("Párrafo");
    paragraphElement.appendChild(paragraphText);
    bodyElement.appendChild(paragraphElement);
  </script>
</html>
Atributo innerHTML Ejemplo
<!DOCTYPE html>
<html>
<head>
  <title>JS DOM. innerHTML</title>
</head>
<body id="body">
  <script>
    let bodyElement = document.getElementById("body");
    bodyElement.innerHTML = "<h1>Título con innerHTML</h1>";
    bodyElement.innerHTML += "<p>Párrafo</p>";
  </script>
</body>
</html>
Aplicación

Gestión de Eventos

  • Lenguaje orientado a eventos elevados por los elementos por las acciones:

    • del usuario con el cursor o el teclado sobre la página

    • del navegador al cargar, abandonar, …​

    • …​

  • Evento es el objeto resultante de cosificar una acción (Karl Marx!!! 8-o) con propiedades y métodos

    • Ejemplo: Disputar un partido de cualquier deporte se convierte en un evento deportivo con fecha, participantes, arbitros, resultado, …​ y posibilidad de apalazar con los avisos correspondientes, cancelar, obtener ganador, …​

    • Evento de Usuario: hacer click en un elemento de la página HTML se convierte en un evento click con posición, tiempo, …​ y posiblidad de cancelar, …​; …​

    • Evento de Navegador: cargar una página HTML se convierte en un evento carga con …​; …​

eventos

Tipos de Eventos

Tipo Propiedad Descripción Clase, funcion constructora

Ratón

mousedown

The event occurs when the user presses a mouse button over an element

MouseEvent

mouseenter

The event occurs when the pointer is moved onto an element

MouseEvent

mouseleave

The event occurs when the pointer is moved out of an element

MouseEvent

mousemove

The event occurs when the pointer is moving while it is over an element

MouseEvent

mouseover

The event occurs when the pointer is moved onto an element, or onto one of its children

MouseEvent

mouseout

The event occurs when a user moves the mouse pointer out of an element, or out of one of its children

MouseEvent

mouseup

The event occurs when a user releases a mouse button over an element

MouseEvent

dblclick

The event occurs when the user double-clicks on an element

MouseEvent

click

The event occurs when the user clicks on an element

MouseEvent

contextmenu

The event occurs when the user right-clicks on an element to open a context menu

MouseEvent

wheel

The event occurs when the mouse wheel rolls up or down over an element WheelEvent mousewheel Deprecated. Use the wheel event instead

WheelEvent

Foco

focus

The event occurs when an element gets focus

FocusEvent

focusin

The event occurs when an element is about to get focus

FocusEvent

focusout

The event occurs when an element is about to lose focus

FocusEvent

blur

The event occurs when an element loses focus

FocusEvent

Arrastrar y soltar

drag

The event occurs when an element is being dragged

DragEvent

dragend

The event occurs when the user has finished dragging an element

DragEvent

dragenter

The event occurs when the dragged element enters the drop target

DragEvent

dragleave

The event occurs when the dragged element leaves the drop target

DragEvent

dragover

The event occurs when the dragged element is over the drop target

DragEvent

dragstart

The event occurs when the user starts to drag an element

DragEvent

drop

The event occurs when the dragged element is dropped on the drop target

DragEvent

Teclado

keydown

The event occurs when the user is pressing a key

KeyboardEvent

keypress

The event occurs when the user presses a key

KeyboardEvent

keyup

The event occurs when the user releases a key

KeyboardEvent

Tampón del teclado, buffer

paste

The event occurs when the user pastes some content in an element

ClipboardEvent

copy

The event occurs when the user copies the content of an element

ClipboardEvent

cut

The event occurs when the user cuts the content of an element

ClipboardEvent

Formulario

submit

The event occurs when a form is submitted

Event

reset

The event occurs when a form is reset

Event

search

The event occurs when the user writes something in a search field (for <input="search">)

Event

change

The event occurs when the content of a form element, the selection, or the checked state have changed (for <input>, <select>, and <textarea>)

Event

toggle

The event occurs when the user opens or closes the <details> element

Event

select

The event occurs after the user selects some text (for <input> and <textarea>)

UiEvent, Event

show

The event occurs when a <menu> element is shown as a context menu

Event

scroll

The event occurs when an element’s scrollbar is being scrolled

UiEvent, Event

hashchange

The event occurs when there has been changes to the anchor part of a URL

HashChangeEvent

Tableta

touchcancel

The event occurs when the touch is interrupted

TouchEvent

touchend

The event occurs when a finger is removed from a touch screen

TouchEvent

touchmove

The event occurs when a finger is dragged across the screen

TouchEvent

touchstart

The event occurs when a finger is placed on a touch screen

TouchEvent

Gestión del documento

beforeunload

The event occurs before the document is about to be unloaded

UiEvent, Event

load

The event occurs when an object has loaded

UiEvent, Event

unload

The event occurs once a page has unloaded (for <body>)

UiEvent, Event

loadedmetadata

The event occurs when meta data (like dimensions and duration) are loaded

Event

loadstart

The event occurs when the browser starts looking for the specified media

ProgressEvent

error

The event occurs when an error occurs while loading an external file

ProgressEvent, UiEvent, Event

invalid

The event occurs when an element is invalid

Event

input

The event occurs when an element gets user input

InputEvent, Event

resize

The event occurs when the document view is resized

UiEvent, Event

fullscreenchange

The event occurs when an element is displayed in fullscreen mode

Event

fullscreenerror

The event occurs when an element can not be displayed in fullscreen mode

Event

abort

The event occurs when the loading of a media is aborted

UiEvent, Event

offline

The event occurs when the browser starts to work offline

Event

online

The event occurs when the browser starts to work online

Event

pagehide

The event occurs when the user navigates away from a webpage

PageTransitionEvent

pageshow

The event occurs when the user navigates to a webpage

PageTransitionEvent

popstate

The event occurs when the window’s history changes

PopStateEvent

storage

The event occurs when a Web Storage area is updated

StorageEvent

transitionend

The event occurs when a CSS transition has completed

TransitionEvent

message

The event occurs when a message is received through the event source

Event

open

The event occurs when a connection with the event source is opened

Event

Animaciones

animationend

The event occurs when a CSS animation has completed

AnimationEvent

animationiteration

The event occurs when a CSS animation is repeated

AnimationEvent

animationstart

The event occurs when a CSS animation has started

AnimationEvent

Video

pause

The event occurs when the media is paused either by the user or programmatically

Event

play

The event occurs when the media has been started or is no longer paused

Event

playing

The event occurs when the media is playing after having been paused or stopped for buffering

Event

waiting

The event occurs when the media has paused but is expected to resume (like when the media pauses to buffer more data)

Event

volumechange

The event occurs when the volume of the media has changed (includes setting the volume to "mute")

Event

progress

The event occurs when the browser is in the process of getting the media data (downloading the media)

Event

ratechange

The event occurs when the playing speed of the media is changed

Event

suspend

The event occurs when the browser is intentionally not getting media data

Event

timeupdate

The event occurs when the playing position has changed (like when the user fast forwards to a different point in the media)

Event

durationchange

The event occurs when the duration of the media is changed

Event

ended

The event occurs when the media has reach the end (useful for messages like "thanks for listening")

Event

loadeddata

The event occurs when media data is loaded

Event

canplay

The event occurs when the browser can start playing the media (when it has buffered enough to begin)

Event

canplaythrough

The event occurs when the browser can play through the media without stopping for buffering

Event

stalled

The event occurs when the browser is trying to get media data, but data is not available

Event

seeked

The event occurs when the user is finished moving/skipping to a new position in the media

Event

seeking

The event occurs when the user starts moving/skipping to a new position in the media

Event

Impresión

afterprint

The event occurs when a page has started printing, or if the print dialogue box has been closed

Event

beforeprint

The event occurs when a page is about to be printed

Event

Clases de eventos

  • Propiedades:

    • type, retorna el string con el nombre del evento

    • target, retorna el elemento que disparó el evento

    • timeStamp, retorna el tiempo en milisegundos relativos a la época

    • …​

  • UiEvent

  • Hereda de Event

  • Hereda de UiEvent

  • Propiedades:

    • key, retorna el valor

    • ctrlKey, retorna si estaba pulsado en combinación con control

    • …​

  • Otros:

  • MouseEvent, WheelEvent, FocusEvent, DragEvent, InputEvent, TouchEvent, ClipboardEvent, AnimationEvent, HashChangeEvent, PageTransitionEvent, PopStateEvent, ProgressEvent, StorageEvent, TransitionEvent

Manejador de Eventos, handle

Modo pull Modo push
  • En vez de estar preguntando a un objeto constantemente si le ha pasado algo, respondiendo con datos, para manejarlo, gestionarlo con ciertas acciones,

  • se convierten esos datos en un evento de cierto tipo, propiedades, y se le hace responsable de llamar a dichas acciones con los datos del evento a todos los que en el momento están registrados, métodos, mostrando interés en él.

  • Ejemplo: en vez de continuar la interacción como cuando eramos un bebe con el que una persona adulta consulta constantemente si hay que cambiar el pañal ante el regalito,

  • nos hacen responsables de avisar (tú llamame a mi!, registro), ante el advenimiento del regalito (estoy a punto! evento), porque así consiguen efectividad (Corre al baño, sube la tapa, sienta, disfruta,…​ y la persona te limpia!!!, acción) y con el tiempo la persona se desrregistra y cuando seamos muy mayores quizás otra persona se vuelva a registrar!!!

  • Patrón Observador / Observado

    • Antiguamente a las acciones, funciones, se le denomminaban callbacks y ésta se registraba/des-registraba en el objeto de interés en ejecutarse asociado a cierto tipo de evento

    • Con la Orientación a Objetos, el bebe, …​ es el observado sobre el que los observadores registran sus funciones, métodos, manejadores/gestores de eventos en cierto tipo de propiedad, atributo.

  • Parámetros de las funciones manejadoras:

    • el evento, event, para consultar tiempo, situación, error, …​ Es opcional, porque ante su ausencia hará referencia al ámbito global que lo ejecuta donde se encuentra el evento declarado

    • el elemento, element, para manipular el objeto observado sobre el que se ejecuta la función como un método del propio objeto. Por tanto, puede elminarse el parámetro y sustituir todas sus referencias por this

  • Registro de las funciones manejadoras:

    • estáticamente medinate HTML con atributos on <TipoEvento> cuyos valores son código javascript, habitualmente, con la llamada que invocará el navegador ante el evento sobre el elemento desde un ámbito donde this es el propio elemento y event está declarado de forma global

      • En el caso de que el código sea más de una expresión, llamada a la función, deberá anteponerse javascript:. Completamente desaconsejado.

    • dinámicamente mediante JavaScript con el métedo addEventListener / removeEventListener presente en todo elemento del arbol DOM cuyos argumentos son:

      • tipo de evento con un string: click

      • función manejadora con un objeto función: onClick (sin invocación ()!!!)

<!DOCTYPE html>
<html>
  <head>
    <title>JS Event</title>
  </head>
  <script>
    function onLoad(event){
      console.log("Evento: " + event.type);
      let body = document.getElementById("body");
      body.addEventListener("copy", onCopy);
      let title = document.getElementById("title");
      title.addEventListener("mouseenter", onMouseEnter);
    }

    function onCopy(event){
      console.log("Evento: " + event.type);
    }

    function onMouseEnter(event){
      console.log("Evento: " + event.type);
    }

    function onBlur(event, input){
      console.log("Evento: " + event.type + " de "
        + input.name + " con " + input.value);
    }

    function onClick(event, button){
      console.log("Evento: " + event.type + " con "
        + button.value);
      let body = document.getElementById("body");
      if (button.value=="Atender al tampón del teclado") {
        button.value = "No atender al tampón del teclado";
        body.addEventListener("copy", onCopy);
      } else {
        button.value = "Atender al tampón del teclado";
        body.removeEventListener("copy", onCopy);
      }
    }

    function onSubmit(event, form){
      let equals = document.getElementById("fieldA").value
        == document.getElementById("fieldB").value;
      if (equals) {
        form.action = "https://"
          + document.getElementById("fieldA").value;
      }
      console.log("Evento: " + event.type);
      return equals;
    }

  </script>
  <!-- manejador establecido estáticamente -->
  <body id="body" onload="onLoad(event)">
    <!-- código establecido estáticamente -->
    <h1 id="title" onmouseleave=
      "javascript: console.log('Evento: ' + event.type); console.log('Evento: ' + event.type);">
        Titulo con foco!!!</h1>
    <!-- validacion/accion del submit: con return!!! -->
    <form id="form"  method="POST"
      onsubmit="return onSubmit(event, this);">
      <label>Campo A: </label>
      <input id="fieldA" type="text"
        onblur = "onBlur(event, this);"/>
      <br>
      <label>Campo B: </label>
      <input id="fieldB" type="text"
        onblur = "onBlur(event, this);"/>
      <br>
      <!-- validación/accion de boton -->
      <input id="button" type="button"
        value="No Atender al tampón del teclado"
        onclick="onClick(event, this);">
      <input type="submit" value="enviar">
    </form>
  </body>
</html>

Propagación de Eventos

  • Una acción del usuario dispara un único evento que será pasado como argumento a todos aquellos elementos en la rama del árbol DOM que tengan registrada la función manejadora del tipo de evento disparado desde el elemento que recibión la interacción hasta el body.

    • Por ejemplo: si toco una pared de un piso de un edificio, también toco el piso del edificio y también todo el edificio

    • Por ejemplo: un click en un celda de una tabla en el _body, podría disparar hasta 4 ejecuciónes de funciones manejadoras de los elementos anidados celda, la fila, la tabla y el body_

  • La propagación establece el orden de la ejecución de las funciones manejadoras para un tipo de evento de los elementos de la rama del árbol DOM:

    • Burbujeo, de dentro a fuera en las cajas de HTML en pantalla, de abajo hacia arriba en el árbol DOM.

      • Para el ejemplo anterior: celda, fila, tabla y cuerpo

    • Goteo, de fuera hacia adentro en las cajas de HTML en pantalla, de arriba hacia abajo en el árbol DOM.

      • Para el ejemplo anterior: cuerpo, tabla, fila, celda

  • Configuración del orden de gestión/manejo

    • Estáticamente con propiedad del elemento de HTML solo para con para ascendente, burbujeo

    • Dinámicamente con registro de observador de JavaScript, en el método addEventListener con un tercer argumento true o false opcional, para goteo o burbujeo respectivamente

  • En cualquier caso se puede detener la propagación de eventos mediante el envio del mensaje stopPropagation al evento

<!DOCTYPE html>
<html>
  <head>
    <title>JS Event. Bubbling and Trickling</title>
                <link rel="stylesheet" href="style.css"/>
                <script language="javascript" src="./logic.js"></script>
        </head>
  <body onload="onLoad();">
    <div class = "nivel-1 izquierda"
      onclick = "alertBubblingFromHTML(event, this);">
      <h1>Nivel 1</h1>
      <h2>Izquierda</h2>
      <div class = "nivel-2 izquierda"
        onclick = "alertBubblingFromHTML(event, this);">
        <h2>Nivel 2</h2>
        <h3>Izquierda</h3>
        <div class = "nivel-3 izquierda"
          onclick = "alertBubblingFromHTML(event, this);">
                                        <h3>Nivel 3</h3>
          <h4>Izquierda</h4>
          <div class = "nivel-4 izquierda"
            onclick = "alertBubblingFromHTML(event, this);">
                                                <h4>Nivel 4</h4>
            <h5>Izquierda</h5>
          </div>
          <div class = "nivel-4 derecha"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Derecha</h5>
          </div>
        </div>
        <div class = "nivel-3 derecha"
          onclick = "alertBubblingFromHTML(event, this);">
          <h3>Nivel 3</h3>
          <h4>Derecha</h4>
          <div class = "nivel-4 izquierda"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Izquierda</h5>
          </div>
          <div class = "nivel-4 derecha"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Derecha</h5>
          </div>
        </div>
      </div>
      <div class = "nivel-2 derecha"
        onclick = "alertBubblingFromHTML(event, this);">
        <h2>Nivel 2</h2>
        <h3>Derecha</h3>
        <div class = "nivel-3 izquierda"
          onclick = "alertBubblingFromHTML(event, this);">
                                        <h3>Nivel 3</h3>
          <h4>Izquierda</h4>
          <div class = "nivel-4 izquierda"
            onclick = "alertBubblingFromHTML(event, this);">
                                                <h4>Nivel 4</h4>
            <h5>Izquierda</h5>
          </div>
          <div class = "nivel-4 derecha"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Derecha</h5>
          </div>
        </div>
        <div class = "nivel-3 derecha"
          onclick = "alertBubblingFromHTML(event, this);">
          <h3>Nivel 3</h3>
          <h4>Derecha</h4>
          <div class = "nivel-4 izquierda"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Izquierda</h5>
          </div>
          <div class = "nivel-4 derecha"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Derecha</h5>
          </div>
        </div>
      </div>
    </div>
    <div class = "nivel-1 derecha"
      onclick = "alertBubblingFromHTML(event, this);">
      <h1>Nivel 1</h1>
      <h2>Derecha</h2>
      <div class = "nivel-2 izquierda"
        onclick = "alertBubblingFromHTML(event, this);">
        <h2>Nivel 2</h2>
        <h3>Izquierda</h3>
        <div class = "nivel-3 izquierda"
          onclick = "alertBubblingFromHTML(event, this);">
                                        <h3>Nivel 3</h3>
          <h4>Izquierda</h4>
          <div class = "nivel-4 izquierda"
            onclick = "alertBubblingFromHTML(event, this);">
                                                <h4>Nivel 4</h4>
            <h5>Izquierda</h5>
          </div>
          <div class = "nivel-4 derecha"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Derecha</h5>
          </div>
        </div>
        <div class = "nivel-3 derecha"
          onclick = "alertBubblingFromHTML(event, this);">
          <h3>Nivel 3</h3>
          <h4>Derecha</h4>
          <div class = "nivel-4 izquierda"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Izquierda</h5>
          </div>
          <div class = "nivel-4 derecha"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Derecha</h5>
          </div>
        </div>
      </div>
      <div class = "nivel-2 derecha"
        onclick = "alertBubblingFromHTML(event, this);">
        <h2>Nivel 2</h2>
        <h3>Derecha</h3>
        <div class = "nivel-3 izquierda"
          onclick = "alertBubblingFromHTML(event, this);">
                                        <h3>Nivel 3</h3>
          <h4>Izquierda</h4>
          <div class = "nivel-4 izquierda"
            onclick = "alertBubblingFromHTML(event, this);">
                                                <h4>Nivel 4</h4>
            <h5>Izquierda</h5>
          </div>
          <div class = "nivel-4 derecha"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Derecha</h5>
          </div>
        </div>
        <div class = "nivel-3 derecha"
          onclick = "alertBubblingFromHTML(event, this);">
          <h3>Nivel 3</h3>
          <h4>Derecha</h4>
          <div class = "nivel-4 izquierda"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Izquierda</h5>
          </div>
          <div class = "nivel-4 derecha"
            onclick = "alertBubblingFromHTML(event, this);">
            <h4>Nivel 4</h4>
            <h5>Derecha</h5>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>
div {
  margin-bottom: 2%;
  position: static;
  float: left;
}

.nivel-1 {
  width: 100%;
  background-color: #61a0a2;
}

div div {
  width: 45%;
  margin-right: 2%;
  margin-left: 2%;
}

.nivel-2 {
  background-color: #5b85c7;
}

.nivel-3 {
  background-color: #629676;
}

.nivel-4 {
  background-color: #c3874c;
}
function onLoad() {
  for (let div of document.getElementsByTagName("div")) {
    // div.addEventListener("click", alertBubblingFromListener);
    // div.addEventListener("click", alertTricklingFromListener, true);
    div.addEventListener("click"
       , alertBubblingFromListenerWithoutPropagation);
     div.addEventListener("click"
       , alertTricklingFromListenerWithoutPropagation, true);
  }
}

function getMsg(event, element) {
  if (event.count == undefined) {
    event.count = 0;
  }
  event.count++;
  return element.getAttribute("class") + " con " + event.count;
}

function alertBubblingFromHTML(event, element) {
  console.log("Bubbling form HTML: " + getMsg(event, element));
}

function alertBubblingFromListener(event) {
  console.log("Bubbling form addEventListener: " + getMsg(event, this));
}

function alertTricklingFromListener(event) {
  console.log("Trickling form addEventListener: "
    + getMsg(event, this));
}

function alertBubblingFromListenerWithoutPropagation(event) {
  console.log("Bubbling form addEventListener without Propagation: "
    + getMsg(event, this));
  if (this.getAttribute("class") === "nivel-2 derecha") {
    console.log("PARA burbujeo");
    event.stopPropagation();
  }
}

function alertTricklingFromListenerWithoutPropagation(event) {
  console.log("Trickling form addEventListener without Propagation: "
    + getMsg(event, this));
  if (this.getAttribute("class") === "nivel-3 izquierda") {
    console.log("PARA goteo");
    event.stopPropagation();
  }
}

Cancelación de Eventos

  • Para prevenir el comportamiento por defecto del navegador ante un evento (por ejemplo: escribir el caracter tras su pulsación, realizar la petición del formulario ante el click en submit, …​) se envia el mensaje preventDefault al evento

<!DOCTYPE html>
<html>
  <head>
    <title>JS Event. Cancelación</title>
  </head>
  <script>
    const DIGITS = /[0-9]/;

    var data = {
      count : 0,
      keys : ""
    }

    function acumulateKeys(event){
      data.count++;
      data.keys += event.key;
    }

    function filterNoDigitsWithPreventDefaul(event){
      if (!DIGITS.test(event.key)){
        event.preventDefault();
      }
    }

    // function filterNoDigitsWithPreventDefaul(event){
    //     var origLastIndex = DIGITS.lastIndex;
    //     DIGITS.lastIndex = 0;
    //     if (!(DIGITS.test(event.key))){
    //     event.preventDefault();
    //   }
    //   DIGITS.lastIndex = origLastIndex;
    // }

    function filterNoDigitsWithReturn(event){
      return DIGITS.test(event.key);
    }

    function showData(){
      data.first = document.getElementsByName("first")[0].value;
      data.second = document.getElementsByName("second")[0].value;
      window.alert(JSON.stringify(data));
    }

  </script>
  <body onkeypress="acumulateKeys(event);">
    <h1>Formulario con enteros filtrados</h1>
    <form>
      <label>Primer número natural: </label>
      <input type="text" name="first" onkeypress="filterNoDigitsWithPreventDefaul(event);">
      <br>
      <label>Segundo número natural: </label>
      <!-- importante el return en el callback!!! -->
      <input type="text" name="second" onkeypress="return filterNoDigitsWithReturn(event);">
      <br>
      <input type="button" value="Mostrar" onclick="showData();">
    </form>
  </body>
</html>

CSS y JavaScript

  • La gestión dinámica de estilos por parte de JavaScript se ciñe a la gestión de la propiedad style presente en todo elemento del árbol DOM que contiene todas las propiedades de estilo correspondientes a cada tipo de elmento: width, position, color, margin, text-align, …​

  • Alternativamente, existe la propiedad cssText del objeto style al que se puede asignar el texto CSS correspondiente a la configuración deseada pero "machaca" las propiedades anteriores.

  • Añadidamente, todo elemento del árbol DOM disfruta de la propiedad classList con los métodos: add, remove, contains, …​

.title {
    color: red;
    font-family: Arial, Helvetica, sans-serif;
}
  • A priori todas las propiedades tienen algún valor predefinido estáticamente por el navegador o por las hojas de estilo del desarrollador tras la carga de la página HTML en el árbol DOM

  • pero dinámicamente el código JavaScript puede recorrer los elementos del árbol DOM y modificar los valores de las propiedades de estilo del objeto style de cada elemento

con funciones

<!DOCTYPE html>
<html>

<head>
  <title>JS CSS. element</title>
  <link rel="stylesheet" type="text/css" href="style.css" />
  <script language="javascript" src="./app.js"></script>
</head>

<body onload="load();">
  <h1>Título</h1>
  <form>
    <input type="button" value="Cambiar color" onclick="changeColor();">
  </form>
</body>

</html>
function load() {
    getTitle().classList.add('title');
}

function getTitle() {
    return document.getElementsByTagName('h1')[0];
}

function changeColor() {
    getTitle().style.color = this.getRandomColor();
}

function getRandomColor() {
    let color = '#';
    for (let i = 0; i < 'RGB'.length; i++) {
        let number = Math.floor(Math.random() * 256).toString(16);
        if (number.length == 1) {
            number = '0' + number;
        }
        color += number
    }
    return color;
}

con objetos

<!DOCTYPE html>
<html>

<head>
  <title>JS CSS. element</title>
  <link rel="stylesheet" type="text/css" href="style.css" />
  <script language="javascript" src="./app.js"></script>
</head>

<body onload="colorChanger .load.bind(colorChanger) ()">
  <h1>Título</h1>
  <form>
    <input type="button" value="Cambiar color" onclick="colorChanger .changeColor.bind(colorChanger) (event, this)">
  </form>
</body>

</html>
class ColorChanger {

    load() {
        // desaconsejado!!!
        this.#getTitle().style.cssText =
            "color:red; font-family:Arial, Helvetica, sans-serif;";
    }

    #getTitle() {
        return document.getElementsByTagName("h1")[0];
    }

    changeColor(event, element) {
        console.log(event);
        console.log(element);
        this.#getTitle().style.color = this.#getRandomColor();
    }

    #getRandomColor() {
        let color = "#";
        for (let i = 0; i < "RGB".length; i++) {
            let number = Math.floor(Math.random() * 256).toString(16);
            if (number.length == 1) {
                number = "0" + number;
            }
            color += number
        }
        return color;
    }

}

const colorChanger = new ColorChanger();
Aplicación

BOM y JavaScript

  • La visualización de una página HTML en una ventana/pestaña del navegador es responsabilidad del objeto global, this, con las siguientes propiedades:

    • window, una referencia a sí mismo

    • document, raíz del árbol DOM correspondiente a la página HTML

    • navigator con propiedades userAgent, para el tipo de navegador y otros como codeName, name, version, language, platform, …​

    • location, con información sobre la URL

    • history, con información de la pila de URLs visitadas

    • y otros como screenX, screenY, screen, screenLeft, screenTop, …​

    • funciones constructoras: Array, Date, Math, String, Function, Boolean, Number, RegExp, …​

    • almacenamiento, permitendo persistir hasta 5Mb de pares clave/valor, con dos string, más allá de la ejecución de la página HTML, con diversa información

      • Por ejemplo: login y password de usuario para futuras sesiones, configuración de idioma, directorios de trabajo por defecto, elementos de un carrito de compra, …​

      • Sustituye a las "antiguas" cookies con capacidad para 4k memoria

      • Existen dos políticas de persistencia:

        • sessionStorage: almacena los datos durante la sesión del navegador

        • localStorage: lmacena los datos para siempre hasta que se borren explícitamente

      • En ambos casos, los objetos disponen de métodos para la gestión de información: setItem (key, value), getItem (key), removeItem (key), …​

<!DOCTYPE html>
<html>
  <head>
    <title>JS BOM. Grabar en el Almacén</title>
    <script>
      function save(input){
        let data = JSON.stringify({
          "constant": "constant",
          "variable": input.value
        });
        //window.sessionStorage.setItem("key", data);
        window.localStorage.setItem("key", data);
      }
    </script>
  </head>
  <body>
    <form>
      <label>Dato:</label>
      <input type="text" onchange="save(this)">
    </form>
    <a href="JS BOM. Storage Consultar.html">Consultar</a>
    <br>
    <a href="JS BOM. Storage Borrar.html">Borrar</a>
  </body>
</html>
<!DOCTYPE html>
<html>
  <head>
    <title>JS BOM. Consultar el Almacén</title>
    <script>
      function get(){
        //let data = window.sessionStorage.getItem("key");
        let data = window.localStorage.getItem("key");
        let text = "NO EXISTE!!!";
        if (data != null){
           text = JSON.parse(data).variable;
        }
        window.alert("Dato: " + text);
      }
    </script>
  </head>
  <body onload="get();">
    <a href="JS BOM. Storage Borrar.html">Borrar</a>
    <br>
    <a href="JS BOM. Storage Grabar.html">Grabar</a>
  </body>
</html>
<!DOCTYPE html>
<html>
  <head>
    <title>JS BOM. Borrar del Almacén</title>
    <script>
      function remove(){
        //window.sessionStorage.removeItem("key");
        window.localStorage.removeItem("key");
      }
    </script>
  </head>
  <body onload="remove();">
    <p>Dato borrado!!!</p>
    <a href="JS BOM. Storage Consultar.html">Consultar</a>
    <br>
    <a href="JS BOM. Storage Grabar.html">Grabar</a>
  </body>
</html>

Sintesis

sintesis

Bibliografía

Obra, Autor y Edición Portada Obra, Autor y Edición Portada

Ponente

  • Luis Fernández Muñoz

setillo

  • Doctor en Inteligencia Artificial por la UPM

  • Ingeniero en Informática por la UMA

  • Diplomado en Informática por la UPM

  • Profesor Titular de ETSISI de la UPM