duduromeroa.com

#Javascript, #DOMJs, #webinteractiva, #Interfaces, #duduromeroa, #Guayaquil

Javascript

Programación para web: Javascript API DOM 5


George Póyla, matemático. Resolver problemas de diseño. www.duduromeroa.com

Por Eduardo J. Romero Andrade
| Guayaquil

Contenido

Eventos de agarrar y soltar (drag / drop)





Eventos de agarrar y soltar

drag / drop

Para estos tipos de eventos es necesario crear áreas de actividad mediante estilos CSS y HTML:

  • ondrop: Activa evento cuando un elemento movible es seleccionado y soltado en el área destino.
  • ondragover: Activa evento cuando una selección movible es arrastrado sobre el área destino.
  • ondragstart: Activa evento cuando el usuario inicia el arrastre de un elemento movible.
  • draggable: Booleano. True para activar selección de arrastre.

El siguiente ejemplo será comentado en sus partes:

En HTML

<!-- Elemento contenedor -->    
<!-- ondrop="agarre()" permite 
que se suelte y se agarre -->  
<!-- Si quitamos evento ondrop 
no se podrá soltar allí nada  -->    
<div class="rectang" 
ondrop="agarre()" 
ondragover="suelta()">

<!-- Elemento interno draggable. 
Activo para drag. Activa función iniciaAgarre()  -->   
<!--Contiene eventos  ondragstart y draggable -->   
<!-- Contiene el id para estilos CSS -->   
<div id="itemMovible" 
ondragstart="iniciaAgarre()" 
draggable="true">Mover</div>
</div>

<!-- Área destino. -->   
<!-- Activa eventos ondrop y ondragover   -->   
<!-- Activa funciones agarre() y nDrop() -->   
<div class="rectang" 
ondrop="agarre()" 
ondragover="suelta()"> 2 </div>

En Javascript

// Crea variable
let elementoDisparadorEvento;

function iniciaAgarre(){
/* Cuanto el evento se activa se guarda 
en 'elementoDisparadorEvento' el elemento 
que activó el evento */
elementoDisparadorEvento = event.target;

console.dir(elementoDisparadorEvento);
// Muestra: div#itemMovible
}
// Que es preventDefault?? 
function suelta(){
/* preventDefault() bloquea el NO 
PERMITIR soltar un elemento desde HTML */
event.preventDefault();
}

function agarre(){
event.preventDefault();
/* Si el elemento disparador es clase rectang... */
if (event.target.className == "rectang"){
/* Al elemento disparador adjuntar el elemento disparador */
event.target.appendChild(elementoDisparadorEvento);

// Cambia color al soltarlo en área destino
document.getElementById("itemMovible").
style.backgroundColor="green";
// Cambia forma al soltarlo en área destino
document.getElementById("itemMovible").
style.borderRadius="50%";
}
}

En CSS

/* ESTILO CSS de ambas cajas */
.rectang{
height: 200px;
width: 200px;
padding: 20px;
margin: 0 50px;
display: inline-block;
border: 1px solid black;
background-color: ;
}

/* EstiloElemento movible */
#itemMovible{
width: 150px;
height: 150px;
background-color: orange;
borderRadius: 10px;
}

xxxx
xxxx

En otro ejemplo, el evento de arraste muestra un texto actualizado según el curso del evento:

En HTML

<!-- Elemento contenedor -->
<div class="areaDestino" 
ondrop="soltar()" 
ondragover="dejarSoltar()">

<!-- Arrastrable -->  
<p ondragstart="iniciarArrastre()" 
ondrag="arrastrando()" 
draggable="true" 
id="itemParaMover">X</p>
</div>

<!-- Sin este elemento no hay texto -->
<p id="demo"></p>

<div class="areaDestino" 
ondrop="soltar()" 
ondragover="dejarSoltar()"></div>  

En Javascript

function iniciarArrastre() {
/* El método DataTransfer.setData() 
establece los datos de arrastre. 
- El primer argumento es el tipo de dato a 
almacenar en el objeto drag. 
- El segundo argumento representa 
el dato a agregar al objeto drag. */
event.dataTransfer.setData("Text", event.target.id);
}

function arrastrando() {
document.getElementById("demo").innerHTML = "Elemento movido";
}

function dejarSoltar() {
// Permite que browser deje soltar elemento 
event.preventDefault();
}

function soltar() {
// Permite que brows
event.preventDefault();

/* El objeto DataTransfer se utiliza 
para contener los datos que se arrastran 
durante una operación de arrastrar y colocar */
const data = event.dataTransfer.getData("Text");
event.target.appendChild(document.getElementById(data));
document.getElementById("demo").innerHTML = "Elemento soltado";
}

En CSS

/* Estilo area destino */
.areaDestino {
width: 100px; 
height: 100px;
padding: 10px;
border: 1px solid black;
}

/* Estilo item movible */
#itemParaMover{
width: 80%;
height: 80%;
background-color: pink;
font-size: 40px;
margin: 0 0px;
}

  • Método dataTransfer.setData(): establece los datos de arrastre. Por ejemplo, añade un id del elemento <p> hacia el objeto DataTransfer. Cuando el evento soltar se activa, se recupera el id y lo usamos para mover el elemento <p> hacia el área destino. - El primer argumento es el tipo de dato a almacenar en el objeto drag. - El segundo argumento representa el dato a agregar al objeto drag.
  • Método DataTransfer.getData(): Recupera el string de un objeto drag pero retorna string vacio. Su argumento es un string que representa el dato a recuperar.
COMBINACIÓN DE EVENTOS DRAG -dragtarget,

drag / drop

Cuando las áreas de destino activan un evento cuando los eventos drag se activan:

En HTML

<!-- Contenedor -->
<div class="areaInicio">

<!-- Objeto movible con evento 'draggable' -->
<p draggable="true" id="objetoMovible">XXXXX</p>
</div>

<p>INICIA TODO</p>

<div class="areaInicio"></div>

<!-- Texto pendiente que se altera luego -->
<p id="pendiente"></p>


En Javascript

/* = = = = =  RECORDAR = = = = = 
event.target siempre obtiene los datos 
del elemento a arrastrar */

/* Eventos activan  */
document.addEventListener("dragstart", function( ) {

/* El método dataTransfer.setData() establece el tipo de datos 
y el valor de los datos arrastrados */
event.dataTransfer.setData("Text", event.target.id);

/* Salida de texto al comenzar a arrastrar el elemento 'p' */
document.getElementById("pendiente").
innerHTML = "Inicia arrastre...";

/* Cambiar la opacidad del elemento arrastrable */
event.target.style.opacity = "0.8";
});

/* Mientras arrastra el elemento 'p', 
cambie el color del texto de salida */
document.addEventListener("drag", function( ) {
document.getElementById("pendiente").style.color = "red";
});

/* Genere algo de texto cuando termine de arrastrar 
el elemento p y restablezca la opacidad  */
document.addEventListener("dragend", function( ) {
document.getElementById("pendiente").
innerHTML = "Finaliza arrastre...";
/* Toma el elemento arrastable */
event.target.style.opacity = "1";
/* Obtiene el elemento con el ID 'pendiente' y 
accede al estilo de 'ancho' */
document.getElementById("pendiente").
style.width = "100px";

document.getElementById("pendiente").
style.heigth = "100px";

document.getElementById("pendiente").
style.backgroundColor = "red";

document.getElementById("pendiente").
style.color = "white";
});

/* Eventos disparados contra el objetivo de caída */
/* Cuando el elemento p arrastrable entre en el areaInicio, 
cambie el estilo de borde del DIVS */
document.addEventListener("dragenter", function( ) {
if ( event.target.className == "areaInicio" ) {
event.target.style.border = "3px solid red";
}
});

/* De forma predeterminada, los datos/elementos no se 
pueden quitar en otros elementos. Para permitir una 
caída, debemos evitar el manejo predeterminado del 
elemento */
document.addEventListener("dragover", function( ) {
event.preventDefault();
});

/* Cuando el elemento p arrastrable abandone el 
areaInicio, restablezca el estilo de borde del DIVS */
document.addEventListener("dragleave", function( ) {
if ( event.target.className == "areaInicio" ) {
event.target.style.border = "";
}
});

/* On drop - Evitar el manejo predeterminado del 
navegador de los datos (el valor predeterminado está 
abierto como enlace en drop). Restablecer el color del 
texto de salida y el color del borde del DIV. Obtenga los 
datos arrastrados con el método dataTransfer.getData() 
Los datos arrastrados son el identificador del elemento 
arrastrado ("drag1"). Anexar el elemento arrastrado 
al elemento de colocación */
document.addEventListener("drop", function( ) {
event.preventDefault();

if ( event.target.className == "areaInicio" ) {

document.getElementById("pendiente").style.color = "";

/* Estilo cuando se finalice drop */
event.target.style.border = "";

var data = event.dataTransfer.getData("Text");

event.target.appendChild(document.getElementById(data));
}
});

En CSS

/* Los dos recuadros tienen este estilo*/
.areaInicio {
width: 100px; 
height: 120px;
padding: 5px;
border: 1px solid black;
}

#objetoMovible{
width: 90px;
height: 90px;
background-color: pink;
}

ANIMANDO ELEMENTOS

drag / drop

Para activar animaciones cuando se ejecuta una acción de click. En el ejemplo inferior se tiene un botón y un recuadro rojo. Al activar el botón se ejecuta la función 'moverCuadro(){}' que a su vez aloja una función 'setInterval( .. )' y que a su vez aloja una función de intervalo. Esta función 'setInterval()' obliga a ejecutar código cuando un lapso de tiempo ha ocurrido.

En HTML

<!-- Se crea elemento boton --->
<button onclick="moverCuadro()"> Ir a la derecha </button>
<!-- Se crea elemento cuadro --->
<div id="cuadro"></div>
<p id="elemento"></p>

En Javascript

function moverCuadro(){
// Nueva variable 'b' aloja el elemento con ID 'cuadro'*/
let b = document.getElementById("cuadro");
/* variable vector 'x' dirige hacia adelante */
let x = 0;
/* variable vector 'm' dirige hacia abajo */
let m = 10;

setInterval(function() {
// Condicional. Si 'x' pasa de cero a 200...
if (x === 200){
      // Limpiar duración de intervalo
      clearInterval();
      /* Pero si 'x' no pasa de 200. Es decir, 
      mientras el valor de 'x' sea menor a 200 */
      } else {
      // Incrementa el valor actual de 'x' en una unidad 
      x++; 
      /* OJO AQUÍ: Se apunta a la variable 'b', 
      se ingresa a las reglas de CSS, 
      se añade propiedad 'left' 
      Y SE ADJUNTA (NO SE SUMA)... */
      b.style.left = x + "px";
      /* Altera posición desde arriba, 
      incrementa dirección */
      b.style.top = m++ + "px";
      }
      /* El intervalo debe durar 1 MILISEGUNDO.
      Es decir, el cuadro se moverá cada milisegundo. 
      Si agregamos el valor de 1000 (un segundo, 
      entonces el cuadro se moverá cada segundo) */
      }, 1);
} 

En CSS

/* Todo 'div' tiene estas reglas */
div{
background-color: red;
width: 100px;
height: 100px;
/* Para que el elemento se coloque 
en la esquina superior izquierda, 
y permita reglas de posicionamiento top, left, etc... */
position: absolute;
}

En otras palabras, la estructura que se siguó para anidar las funciones fue:

En Javascript

function moverCuadro(){

// variables
/* document.getElementById... para apuntar 
al elemento div que deseamos alterar */

      setInterval(function() {
      // condicional: siempre que el valor de 'x' 
      // NO SEA IGUAL a la una distancia en pixeles dada 
      if(/*condicion*/){
      clearInterval();
      } else {
      // Incrementar 'x' y añadir un valor nuevo
      // Apuntar a valores y agregarles pixel
      }
      }
}

REGISTRAR ACTIVIDAD DE LOS ELEMENTOS AL SER CLICKEADOS

pendiente...


BIBLIOGRAFÍA:
    3ra edición. 2018. Marijn Haverbeke. No starch press.
    [2] MDN Web Docs, Javascript. Mozilla Foundation.
    David Flanagan (2020). Editorial O'Reilly.
    Ved Antani, Stoyan Stefanov (2017). Packt Publishing.
    Editorial Packt.
    Information and Computation. Elsevier.
    ACM SIGCSE