viernes, 26 de julio de 2013

HTML5: DRAG & DROP NATIVO

HTML5 incorpora muchas funcionalidades y etiquetas que harán la vida más sencilla a los desarrolladores web. En este artículo vamos a ver dos de ellas en dos ejemplos: el Drag & Drop nativo y los nuevos métodos de acceso al árbol DOM. Se supone que en el futuro todos los navegadores deberán implementar todas las características del estándar aunque a día de hoy no todos los navegadores cumplen con estos estándares. Para comprobar el nivel de compatibilidad de la versión de vuestro navegador podéis pulsar sobre el siguiente enlace.

Anteriormente a HTML5 podíamos simular el proceso de Drag & Drop con librerías como MooTools o JQuery. El nuevo HTML5 ya incorpora está característica de forma nativa y vamos a verlo con el siguiente ejemplo.

En en el proceso de Drag & Drop hay un objeto que es arrastrado y otro elemento al que se pueden arrastrar objetos. A continuación explicamos los atributos y métodos que debemos implementar en cada uno de los elementos para que puedan ser arrastrados o arrastrar objetos a él.


Objetos arrastrables

Para hacer un objeto arrastrable debemos añadir los siguientes atributos:

  • draggable = true. Con esto indicamos que el elemento puede ser arrastrado.
  • ondragstart. Aquí se define la función que se llevará a cabo cuando se comience a arrastrar el elemento.
  • ondragend. Aquí se define la acción que se lleva a cabo cuando se termina de arrastrar el elemento.
Objetos a los que podemos arrastrar otros objetos

  • ondragenter. Aquí se define la acción que se lleva a cabo cuando un elemento arrastrable entra dentro del elemento.
  • ondragover. Aquí se define la acción que se realiza cuando un elemento arrastrable está sobre el elemento. Debemos definir que tipos de objetos puedes soltarse aquí.
  • ondragleave. Aquí se define la acción que se ejecuta cuando el elemento arrastrable dejar de estar encima del elemento.
  • ondrop. Aquí se indica la acción que se lleva a cabo cuando se suelte el elemento arrastrable sobre el objeto contenedor.

En el primer ejemplo tenemos dos contenedores en el que tenemos varios personajes de Juegos de Tronos y los tenemos que clasificar en Buenos y Malos. El código completo lo podemos descargar de aquí.

Cada personaje es un enlace (<a>) y está contenido en un fieldset. Hay tres fieldset: uno para personajes, otra para los personajes buenos y otro para los malos.

Para hacer arrastrable a un personaje:

 <a draggable="true" onDragStart="dragItem(this, event)" onDragEnd="dragEnd(this, event)" class="item" id="ES">Eddard Stark</a>

A continuación implementamos las acciones asociadas al drag:


function dragItem(item, event) {
        event.dataTransfer.setData('Dato', item.id);
        item.style.opacity = '0.3';
    }
    
    function dragEnd(item, event) {
        item.style.opacity = '';        
    }

En dragItem nos guardamos el id del elemento arrastrable para tenerlo disponible en el drop y aplicamos transparencia al elemento para distinguir cuando lo estamos arrastrando. En dragEnd restablecemos la opacidad del elemento.


Y por último lo que haríamos sobre el elemento al que se pueden arrastrar elementos es lo siguiente:



<fieldset id="buenos" class="container" onDrop="dropItem(this, event)" onDragEnter="return false" onDragOver="return false">


En las funciones onDragEnter y onDragOver no hacemos nada. Al no hacer nada en onDragOver vamos a permitir que cualquier personaje puede arrastrarse hasta este contenedor. En la función onDrop comprobamos el fieldset al que estamos arrastrando el personaje para cambiar de color el fondo del mismo y posteriormente lo añadimos al contenedor.


function dropItem(target, event) { 
        var dato = event.dataTransfer.getData('Dato');
        var item = document.getElementById(dato)
        if (target.id == 'buenos') {
         item.className = 'item itemBueno';
        } else if (target.id == 'malos') {
         item.className='item itemMalo';
        } else if (target.id == 'origen') {
         item.className='item';
        }
        target.appendChild(item);
    }

En el contenedor al que se arrastran objetos podemos establecer que actúe como una papelera o también como un clonador de objetos. Os pongo lo que habría que poner en la función dropItem para clonar objetos:


function dropItem(target, event) { 
        var dato = event.dataTransfer.getData('Dato');
        var item = document.getElementById(dato);   
        target.appendChild(item.cloneNode(true));
    }


Un ejemplo con la clonación de objetos lo podéis ver aquí. Es parecido al caso anterior aunque ahora tendremos dos contenedores, uno para artículos y otro para la lista de la compra. Iremos arrastrando los artículos a la lista pero ahora no se borrarán porque podemos tener varias unidades de un mismo artículo. Las posibilidades que nos permite el Drag & Drop  son muy amplias y depende de nuestra imaginación el valor añadido que podamos dar a nuestro proyectos.




Por último hemos visto en el primer ejemplo hay dos botones con los que podemos consultar los personajes que hemos arrastrado tanto a buenos como a malos. Para ellos utilizamos las nuevas funciones de HTML5 para acceder al árbol DOM. En nuestro caso utilizamos la función querySelectorAll para recuperar los elementos de tipo <a> dentro de un fieldset concreto.  Aquí tenéis un ejemplo para recuperar los personajes buenos:


 function verBuenos(){
  var buenos = document.querySelectorAll('#buenos a');
  for (var i=0; i < buenos.length; i++) {
   alert(buenos[i].innerHTML);
  }
    }

Espero que os sea útil.

Salu2.

No hay comentarios:

Publicar un comentario en la entrada