Arrastrar y soltar en HTML5

Codigo html
La forma más fácil de insertar un iFrames
22 enero, 2017
Show all

Arrastrar y soltar en HTML5

18ixdorz2ibjgjpg

La función de arrastrar y soltar (Drag and Drop) tiene una gran importancia en HTML5. En la especificación se define un mecanismo basado en eventos, el API de JavaScript y elementos de marcado adicionales para indicar que prácticamente cualquier tipo de elemento de una página se pueda arrastrar. Es difícil tener algo en contra de la compatibilidad nativa de un navegador con una determinada función. La compatibilidad nativa del navegador con la función DnD permite ofrecer aplicaciones web más interactivas.


Para hacer posible la función de arrastrar y soltar se incorporan nuevos eventos del ratón. Todos ellos crean un objeto “event” que es el elemento desde el que activa el evento. ondragstart: Se inicia un arrastrado. ondrag: Se produce con cada movimiento del ratón mientras se arrastra un elemento. ondragover: Se produce con cada movimiento del ratón cuando se arrastra un elemento dentro del receptor de soltado. ondragenter: El elemento arrastrado entra dentro de un receptor de soltado. ondragleave: El elemento arrastrado sale fuera de un receptor de soltado. ondrop: Se produce al soltar un elemento dentro del receptor de soltado. ondragend: Se produce al acabar el arrastre, ya sea dentro del receptor de soltado o no.

Todos estos eventos detectan un objeto “event” que recogemos en la función que maneja el evento. Este objeto es, o bien el objeto arrastrado, o el receptor de soltado. Además permiten realizar diferentes acciones con otros elemento como cualquier función. Los eventos ondrop y ondragover se aplican al receptor de soltado, los demás eventos se aplican al elemento arrastrado. Explicamos ahora cuáles son estos elementos. En primer lugar debemos definir qué elementos queremos que puedan arrastrarse. Para ello les pondremos a cada uno de ellos el atributo: draggable=”true” Este atributo convierte al elemento en un elemento que puede ser arrastrado. Para detectar el arrastre utilizaremos también el evento ondragstart al cual le asociaremos una función en la que pondremos el argumento event para detectar el evento.

<p draggable="true" ondragstart="evdragstart(event)">elemento 1</p>

Esto sería el código básico que aplicamos en HTML5 al elemento arrastrado. Debemos poner siempre el atributo draggable=”true”. Además, como mínimo, debemos poner el evento ondragstart. Este evento nos lleva a una función que aquí hemos llamado evdragstart, y que veremos luego. Debemos poner como argumento el objeto event, que da información sobre el evento. Podríamos poner también en el elemento arrastrado otros eventos (ondragenter, ondragleave, ondragend, ondrag). Estos no son obligatorios para realizar el arrastre, y se usan cuando se quiere resaltar algún elemento de la página durante el recorrido del elemento en el arrastre. El receptor de soltado es el elemento dentro del cual dejamos el elemento arrastrado. De manera predeterminada no existe ningún receptor de soltado, por lo que debemos indicarlo de alguna manera. Puede haber más de un receptor de soltado siempre y que lo indiquemos.

Para indicar el receptor de soltado, al elemento o elementos que utilicemos para este fin debemos poner los eventos ondragover y ondrop.

<div id="soltado" ondragover="evdragover(event)" ondrop="evdrop(event)"></div>

Aquí los eventos anteriores los recogemos en las funciones evdragover para el evento ondragover, yevdrop para el evento drop. Ambas funciones llevan el objeto event como argumento. Más adelante veremos cómo deben ser estas funciones. A partir de aquí seguimos con el código en javascript.

El objeto event recogido en los eventos anteriores tiene el método dataTransfer que nos permitirá recoger el contenido del objeto arrastrado. La propiedad dataTransfer tiene a su vez unos métodos y propiedades que se utilizan para obtener la información del objeto arrastrado, por ejemplo:

texto=event.dataTransfer.getData("Text");

Esta línea nos devuelve la información del contenido del elemento arrastrado. Los métodos y propiedades de dataTransfer son:

getData(): Indica el tipo de contenido que debe ser volcado en el evento.

setData(): Indica el tipo de contenido asociado que queremos recoger del evento.

clearData(): Para borrar el contenido del evento. Propiedades

dropEffect: Indica el tipo de la operación de arrastrar y soltar. Sus valores pueden ser: none, move, copy, link, copymove, copylink, linkmove, all.

effectAlowed: Indica el tipo permitido para de arrastrar y soltar. Sus valores pueden ser: none, move, copy, link. Los únicos necesarios para realizar un arrastre son los métodos getData() y setData().

Al utilizar los eventos que se aplican al receptor de soltado, debemos utilizar el método preventDefault() sobre el elemento event. Este método elimina el comportamiento por defecto del navegador permitiendo así el arrastre. También es conveniente utilizar el método stopPropagation() sobre el elemento event al aplicarlo en el evento ondrop. Evitamos así comportamientos por defecto en algunos elementos como los enlaces. Estos dejan de comportarse de manera habitual y pueden ser arrastrados sin abrir la página a la que apuntan.

Ejemplo de arrastrar y soltar

Un buen ejemplo de arrastrar y soltar en el que podemos intercambiar elementos entre dos contenedores. En primer lugar creamos el código HTML, en el que ponemos, dentro de un contenedor general, cuatro contenedores que serán los receptores de soltado. Dentro de éstos pondremos las imagenes arrastrables y una papelera para eliminar los elementos seleccionados.

Para empezar con este ejemplo crearemos una sección que contendrá los Divs (uno para cada fotografía o icono y otro para la papelera) añadiendo la propiedad draggable=”true” refiriéndonos a que este Div como arrastrable.


<body>

<h2>Drag and Drop</h2>

<section id="galeria">
    <div id="bloque-0" class="bloque-imagen" ondrop="drop(event)" ondragover="allowDrop(event)" ondragenter="changeClass(this)" ondragleave="restoreClass(this)">
        <img src="http://design.laparideradeideas.es/wp-content/uploads/2017/03/icono1.jpg" draggable="true" ondragstart="drag(event)" id="drag1"/>
    </div>

    <div id="bloque-1" class="bloque-imagen" ondrop="drop(event)" ondragover="allowDrop(event)" ondragenter="changeClass(this)" ondragleave="restoreClass(this)">
        <img src="http://design.laparideradeideas.es/wp-content/uploads/2017/03/icono4.jpg" draggable="true" ondragstart="drag(event)" id="drag2"/>
    </div>
    
    <div id="bloque-2" class="bloque-imagen" ondrop="drop(event)" ondragover="allowDrop(event)" ondragenter="changeClass(this)" ondragleave="restoreClass(this)">
        <img src="http://design.laparideradeideas.es/wp-content/uploads/2017/03/icono2.jpg" draggable="true" ondragstart="drag(event)" id="drag3"/>
    </div>
    
    <div id="bloque-3" class="bloque-imagen" ondrop="drop(event)" ondragover="allowDrop(event)" ondragenter="changeClass(this)" ondragleave="restoreClass(this)">
        <img src="http://design.laparideradeideas.es/wp-content/uploads/2017/03/icono3.jpg" draggable="true" ondragstart="drag(event)" id="drag4"/>
    </div>
</section>

<div id="bloque-4" class="cajapapelera">
        <img class="papelera" src="http://design.laparideradeideas.es/wp-content/uploads/2017/03/papelera.png" id="drag5" ondrop="eliminar(event);" ondragover="allowDrop(event)" />
</div>
</body>

Le damos los estilos a los divs y el resto de partes de la sección:

<style type="text/css">
    
.bloque-arrastra-aqui {
    background-color: whitesmoke;
    outline: red dashed 3px;
    opacity: 0.5;
    border-radius: 5px;
}    
    
.bloque-imagen {
   text-align: center;      
   border-radius: 5px;
   padding: 5px;
    float: left;
    width: 100px;
    height: 97px;
    margin: 10px;
    border: 1px solid red;
}

#galeria {
    margin: 0 auto;
    padding: 10px;
    outline: 2px solid black;
    border-radius: 5px;
    height: 130px;
    width: 528px;
    position: absolute;
    
}
.papelera {
    margin-top: 25px;
    padding-left: 30px;
    text-align: center;      
    float: left;
    width: 100px;
    height: 100px;
}
.cajapapelera {
    float: left;
    margin-left: 560px;
    padding-left: 30px;
    text-align: center;      
}
</style>

A continuación creamos las funciones javascript:

<script type="text/javascript">
  function allowDrop(ev) {
    ev.preventDefault();
}

function drag(ev) {
    ev.dataTransfer.setData("idImgOrigin", ev.target.id);
    ev.dataTransfer.setData("idDivOrigin", ev.target.parentNode.id);
}

function drop(ev) {
    ev.preventDefault();
    createNewBlock(ev);
}

function checkOrderPlacement(ev) {
    var idTargetNumber = ev.target.id.split("-")[1];
    var idOriginNumber = ev.dataTransfer.getData("idDivOrigin").split("-")[1];
    
    if (idTargetNumber > idOriginNumber) return "right";
    else if(idTargetNumber < idOriginNumber) return "left";
}

function renumberIdDivs() {
    var divs = document.getElementById("galeria").getElementsByTagName("div");
    for(var i = 0; i<divs.length; i++) {
        divs[i].id = "bloque-" + i;
    }
}

function createNewBlock(ev) {
    var orderPlacement = checkOrderPlacement(ev);
    restoreClass(ev.target);
    if (ev.target.id=="bloque-4"){
        eliminar(ev);
    }else{
        if (orderPlacement == "left" || orderPlacement=="right") {
            
            var divClonado = document.getElementById(ev.target.id).cloneNode(true);
            restoreClass(divClonado);
            document.getElementById("galeria").insertBefore(divClonado, ev.target);

            var divOrigin = document.getElementById(ev.dataTransfer.getData("idDivOrigin"));
            
            if (orderPlacement == "right") {
                document.getElementById("galeria").replaceChild(divOrigin, ev.target);
            }
            else if (orderPlacement == "left") {
                document.getElementById("galeria").replaceChild(divOrigin, divClonado);
            }
            
            renumberIdDivs();
        }
    }
}

function changeClass(bloque) {
    bloque.firstElementChild.style.display = "none";
    var clases = bloque.className.split(" ");
    if (clases.length < 2 ) {
        clases = bloque.className + " " + "bloque-arrastra-aqui";
        bloque.className = clases;
    }
}

function restoreClass(bloque) {
    bloque.firstElementChild.style.display = "inherit";
    var clases = bloque.className.split(" ");
    if (clases.length >= 2 ) {
        bloque.className = clases[0];
    }
}

function eliminar(ev) {
    ev.preventDefault();
    var idDivOrigin = ev.dataTransfer.getData("idDivOrigin");
    var elementoDivOrigin = document.getElementById(idDivOrigin);
    document.getElementById("galeria").removeChild(elementoDivOrigin);
    /*
    var elementoArrastrado = document.getElementById(ev.dataTransfer.getData("galeria"));
    alert(elementoArrastrado.id);
    elementoArrastrado.parentNode.removeChild(elementoArrastrado);*/
        }
</script>

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>