Ir al contenido principal

Arrastrar y soltar (HTML 5)



Los nuevos eventos JavaScript y atributos de HTML 5 nos permiten la interacción con nuestro documento / aplicación utilizando la técnica de arrastrar y desplazar. La interfazDataTransfer nos permite transferir archivos utilizando las capacidades de arrastrar y soltar.


Tabla de contenido


Los eventos de arrastrar y soltar

Existen los siguientes eventos para controlar la interacción del usuario usando arrastrar y soltar.
drag - El cursor ha arrastrado el elemento.
dragenter - El cursor ha arrastrado algo dentro el elemento.
dragleave - El cursor ha quitado algo que esta arrastrando de sobre el elemento.
dragover - El cursor ha arrastrado algo por encima del elemento. El evento por defecto bloquea la posibilidad de soltar en cada elemento, podemos permitir soltar en un elemento haciendo que devuelva false.
dragstart - Empezamos a arrastrar un elemento.
drop - Se ha soltado algo dentro de el elemento.
dragend - Se ha terminado de arrastrar un elemento.


Definiendo que y donde arrastrar

Con el atributo draggable indicamos al navegador que un elemento dado se puede arrastrar
 
000
001
002
003 
<body>
  <div draggable="true">Este elemento se puede arrastrar</div>
  <div>Este otro no</div>
</body>
 
Y haciendo devolver false al evento dragover hacemos que se pueda arrastrar sobre un elemento:
 
000
001
002
003
004
005
006
007
008
009
010
011 

<body>
  <div draggable="true">Este elemento se puede arrastrar</div> 
  <div id="aqui">Aqui se puede arrastrar</div>
  <script>
    function alarrastraraqui () {
      return false;
    }
    // Vinculamos la función al evento del div con ID=aqui    document.getElementById('aqui').ondragover = alarrastraraqui;
  
</script>
</body>
 


Personalizando el comportamiento de arrastrar soltar

Podemos cambiar la forma en que se comporta el soltar sobre un elemento con el atributo dropEfect de dataTransfer en el evento ondragover, de esta forma podemos escojer entre none, copy, link y move:
 
000
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029 
<body>
  <div draggable="true">Este elemento se puede arrastrar</div> 
  <div id="aqui_none">Aqui se puede arrastrar ( efecto: ninguno )</div> 
  <div id="aqui_copy">Aqui se puede arrastrar ( efecto: copiar )</div> 
  <div id="aqui_link">Aqui se puede arrastrar ( efecto: enlazar )</div> 
  <div id="aqui_move">Aqui se puede arrastrar ( efecto: mover )</div>
  <script>
    // Definimos el comportamiento al soltar sobre un elemento    function alarrastraraqui_none () {
      e.dataTransfer.dropEffect = 'none';
      return false;
    }
    function alarrastraraqui_copy () {
      e.dataTransfer.dropEffect = 'copy';
      return false;
    }
    function alarrastraraqui_link () {
      e.dataTransfer.dropEffect = 'link';
      return false;
    }
    function alarrastraraqui_move () {
      e.dataTransfer.dropEffect = 'move';
      return false;
    }
    document.getElementById('aqui_none').ondragover = alarrastraraqui_none;
    document.getElementById('aqui_copy').ondragover = alarrastraraqui_copy;
    document.getElementById('aqui_link').ondragover = alarrastraraqui_link;
    document.getElementById('aqui_move').ondragover = alarrastraraqui_move;
  
</script>
</body>
 
Según en que div situemos el elemento arrastrado el icono del navegador será diferente.

En el evento dragstart podemos personalizar el elemento arrastrado, el atributoeffectAllowed del dataTransfer del evento indica que métodos de arrastrado permite un elemento, sus valores pueden ser none, copy, copyLink, copyMove, link, linkMove, moveall.

En el ejemplo vemos cómo segun el effectAllowed podemos arrastrar o no a diferentesdiv con dropEffect distinto:
 
000
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045 

<body>
  <div id="esto_none" draggable="true">Este elemento se puede arrastrar (permite: none)</div>
  <div id="esto_all" draggable="true">Este elemento se puede arrastrar (permite: all)</div>
  <div id="esto_copyMove" draggable="true">Este elemento se puede arrastrar (permite: copyMove)</div>
  <div id="aqui_none">Aqui se puede arrastrar ( efecto: none )</div> 
  <div id="aqui_copy">Aqui se puede arrastrar ( efecto: copy )</div> 
  <div id="aqui_link">Aqui se puede arrastrar ( efecto: link )</div> 
  <div id="aqui_move">Aqui se puede arrastrar ( efecto: move )</div>
  <script>
    // Definimos el comportamiento al soltar sobre un elemento    function alarrastraraqui_none () {
      e.dataTransfer.dropEffect = 'none';
      return false;
    }
    function alarrastraraqui_copy () {
      e.dataTransfer.dropEffect = 'copy';
      return false;
    }
    function alarrastraraqui_link () {
      e.dataTransfer.dropEffect = 'link';
      return false;
    }
    function alarrastraraqui_move () {
      e.dataTransfer.dropEffect = 'move';
      return false;
    }
    // Definimos el comportamiento que permitimos al soltar un elemento    function alarrastraresto_none () {
      e.dataTransfer.effectAllowed = 'none';
    }
    function alarrastraresto_all () {
      e.dataTransfer.effectAllowed = 'all';
    }
    function alarrastraresto_copyMove () {
      e.dataTransfer.effectAllowed = 'copyMove';
    }
    document.getElementById('aqui_none').ondragover = alarrastraraqui_none;
    document.getElementById('aqui_copy').ondragover = alarrastraraqui_copy;
    document.getElementById('aqui_link').ondragover = alarrastraraqui_link;
    document.getElementById('aqui_move').ondragover = alarrastraraqui_move;
    document.getElementById('esto_none').ondragstart = alarrastraresto_none;
    document.getElementById('esto_all').ondragstart = alarrastraresto_all;
    document.getElementById('esto_copyMove').ondragstart = alarrastraresto_copyMove;
  
</script>
</body>
 
Y por otro lado, con el método setDragImage marcamos el elemento que ve el usuario al arrastrar, la distancia X del cursor y Y.

En el ejemplo, hay 3 div arrastrables y 3 div que se ven al lado del cursor según que div arrastramos:
 
000
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028 
<body>
  <!--  Esto es lo que arrastramos -->
  <div id="esto_img_1" draggable="true">Este elemento se puede arrastrar (se ve: img_1)</div>
  <div id="esto_img_2" draggable="true">Este elemento se puede arrastrar (se ve: img_2)</div>
  <div id="esto_img_3" draggable="true">Este elemento se puede arrastrar (se ve: img_3)</div>
  <br/>
  <br/>
  <br/>
  <br/>
  <!--  Esto es lo que vemos cuando arrastramos lo anterior -->
  <div id="img_1" style="background: red">IMG 1</div>
  <div id="img_2" style="background: green">IMG 2</div>
  <div id="img_3" style="background: blue">IMG 3</div>
  <script>
    // Indicamos las imágenes en cada evento    function alarrastraresto_img_() {
      e.dataTransfer.setDragImage  ( document.getElementById('img_1'), 0,);
    }
    function alarrastraresto_img_() {
      e.dataTransfer.setDragImage  ( document.getElementById('img_2'), 0,);
    }
    function alarrastraresto_img_() {
      e.dataTransfer.setDragImage  ( document.getElementById('img_3'), 0,);
    }
    document.getElementById('esto_img_1').ondragstart = alarrastraresto_img_1;
    document.getElementById('esto_img_2').ondragstart = alarrastraresto_img_2;
    document.getElementById('esto_img_3').ondragstart = alarrastraresto_img_3;
  
</script>
</body>
 


Accediendo al contenido arrastrado

Para acceder al contenido arrastrado primero debemos indicar el contenido condataTransfer.setData, una vez indicado podemos acceder a éste condataTransfer.getData. Ambos métodos necesitan el primer parámetro indicando el tipo de contenido ( Text o DownloadURL ) y setData un segundo parámetro con el valor
 
000
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031 
<body>
  <div id="esto" draggable="true">Este elemento se puede arrastrar</div>
  <div id="esto2" draggable="true">Este también</div>
  <br />
  <div id="aqui">Arrastrar aqui</div> 
  <script>
    // Evento al empezar a arrastrar un div    function alarrastraresto () {
      // Definimos el contenido del div cómo valor arrastrado de tipo Text      e.dataTransfer.setData('Text', this.innerHTML );
      // Permitimos soltar en zonas de copia      e.dataTransfer.effectAllowed = 'copy';
    }
    // Evento al arrastrar por encima de "Arrastrar aqui"    function alarrastraraqui () {
      // Permitimos copiar       e.dataTransfer.dropEffect = 'copy';
      // Permitimos soltar       return false;
    }
    // Evento al soltar    function alsoltar () {
      // Alertamos el valor de tipo Text definido en alarrastraresto      alert ( e.dataTransfer.getData('Text') );
    }
    // Enlazamos los eventos    document.getElementById('aqui').ondragover = alarrastraraqui;
    document.getElementById('esto').ondragstart = alarrastraresto;
    document.getElementById('esto2').ondragstart = alarrastraresto;
    document.getElementById('aqui').ondrop = alsoltar;
  
</script>
</body>
 
Si se arrastra un fragmento de texto ( de una web, o desde el ordenador ) no hace falta elsetData.

Arrastrando archivos del navegador al ordenador

Para arrastrar archivos del navegador al ordenador del usuario, definiremos el valor del dato arrastrado de tipo DownloadURL con dataTransfer.setData igual que en el punto anterior hicimos con un tipo text. Este valor será:

TIPO MIME:NOMBRE ARCHIVO:RUTA

El siguiente ejemplo descarga un archivo de nombre logo.gif, tipo mime image/gif y con url http://www.programacionweb.net/logo_pweb.gif, el valor tipo DownloadURL esimage/gif:logo.gif:http://www.programacionweb.net/logo_pweb.gif
 
000
001
002
003
004
005
006
007
008
009 
<body>
  <div id="esto" draggable="true">Arrastrar esto a tu ordenador</div> 
  <script>
    function alarrastraresto () {
      e.dataTransfer.setData('DownloadURL', "image/gif:logo.gif:http://www.programacionweb.net/logo_pweb.gif" );
      e.dataTransfer.effectAllowed = 'copy';
    }
    document.getElementById('esto').ondragstart = alarrastraresto;
  
</script>
</body>
 

Arrastrando archivos del ordenador al navegador

El vector files accede a los archivos arrastrados desde el navegador, se pueden arrastrar múltiples archivos que se accederán desde files[0] , files[1], ... , files[n]. Cada file tendrá los siguientes atributos:
fileName - Nombre de archivo
fileSize - Tamaño del archivo
En este ejemplo, podemos soltar archivos desde el ordenador a "Arrastrar archivos aqui", un alert nos mostrará el nombre del archivo:
 
000
001
002
003
004
005
006
007
008
009
010
011
012
013
014 
<body>
  <div id="aqui">Arrastrar archivos aqui</div> 
  <script>
    function alarrastraraqui () {
      e.dataTransfer.dropEffect = 'copy';
      return false;
    }
    function alsoltar () {
      // Obtenemos el nombre del primer archivo ( files[0] )      alert ( e.dataTransfer.files[0].fileName );
    }
    document.getElementById('aqui').ondragover = alarrastraraqui;
    document.getElementById('aqui').ondrop = alsoltar;
  
</script>
</body>
 
Una vez obtenido el archivo podemos subirlo al servidor por ajax:
 
000
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024 
<body>
  <div id="aqui">Arrastrar archivos aqui</div> 
  <script>
    function alarrastraraqui () {
      e.dataTransfer.dropEffect = 'copy';
      return false;
    }
    function alsoltar () {
      var reader = new FileReader();
      reader.onload = function( binaryFile ) {
        // Creamos el objeto AJAX         ajax = new XMLHttpRequest ();
        // Indicamos el script de upload del servidor         ajax.open("post", "/upload.php", true);
         ajax.setRequestHeader("Content-Type", "multipart/form-data");
        // Enviamos el contenido del archivo de vídeo         ajax.send( binaryFile.target.result )
      };
   
      reader.readAsDataURL(e.dataTransfer.files[0]);
    }
    document.getElementById('aqui').ondragover = alarrastraraqui;
    document.getElementById('aqui').ondrop = alsoltar;
  
</script>
</body>

Comentarios

Entradas populares de este blog

Como descargar e instalar Fuentes en tu PC

Los  distintos tipos de letras nos permiten generar trabajos impresos de mejor calidad.  De allí la importancia de poseer en nuestra computadora de un gran número de fuentes entre las cuales elegir. Tanto los   profesionales del diseño gráfico   como todos aquellos que solemos utilizar nuestra computadora para realizar trabajos impresos, conocemos la importancia de disponer de un importante número de fuentes. 

C# - Jerarquia de Operaciones - .NET

El problema de no tomar en cuenta la jerarquía de los operadores al plantear y resolver una operación casi siempre conduce a resultados muchas veces equivocados como estos:

(Blogger) Corazones que sube por el blog

Cupido ya está a la vuelta de la esquina y ahora no es el amor el que está en el aire sino los corazones, muchos corazones. Giffy.me  nos ofrece estos dos scripts que harán que tu blog se inhunde de romanticismo al mostrar muchos  corazones subiendo como globos por el blog . Son dos diseños, el primero son corazones color rosa de un tamaño mediano, el segundo son corazones pequeños en color rojo; en ambos casos los corazones subirán por la página moviéndose de un lado al otro.