En esta publicación, se explican los conceptos básicos de la función arrastrar y soltar.
Cómo crear contenido arrastrable
En la mayoría de los navegadores, las selecciones de texto, las imágenes y los vínculos pueden arrastrarse de forma predeterminada. Por ejemplo, si arrastras un vínculo en una página web, verás un pequeño cuadro con un título y la URL que puedes colocar en la barra de direcciones o en el escritorio para crear una atajo o navega hasta el vínculo. Para que otros tipos de contenido sean arrastrables, debes usar las APIs de arrastrar y soltar de HTML5.
Para que un objeto sea arrastrable, configura draggable=true
en ese elemento. Casi
se puede arrastrar cualquier elemento, como imágenes, archivos, vínculos, archivos
el lenguaje de marcado en tu página.
En el siguiente ejemplo, se crea una interfaz para reorganizar las columnas que se han
diseñado con la cuadrícula de CSS. El lenguaje de marcado básico de las columnas se ve de la siguiente manera:
El atributo draggable
de cada columna configurada como true
:
<div class="container">
<div draggable="true" class="box">A</div>
<div draggable="true" class="box">B</div>
<div draggable="true" class="box">C</div>
</div>
A continuación, se muestra el código CSS para los elementos del contenedor y el cuadro. El único CSS relacionado
la función de arrastre es la cursor: move
propiedad. El resto del código controla el diseño del contenedor
y los elementos de caja.
.container {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
}
.box {
border: 3px solid #666;
background-color: #ddd;
border-radius: .5em;
padding: 10px;
cursor: move;
}
En este punto, puedes arrastrar los elementos, pero no sucederá nada más. Para agregar debes usar la API de JavaScript.
Cómo escuchar eventos de arrastre
Para supervisar el proceso de arrastre, puedes escuchar cualquiera de los siguientes eventos:
Para controlar el flujo de arrastre, necesitas algún tipo de elemento fuente (en el que el arrastre la carga útil de datos (lo que se arrastra) y un objetivo (un área para la caída). El elemento fuente puede ser casi cualquier tipo de elemento. El el destino es la zona de la función de soltar o el conjunto de estas que acepta los datos que utiliza el usuario están tratando de caer. No todos los elementos pueden ser objetivos. Por ejemplo, tu objetivo no puede sea una imagen.
Cómo iniciar y finalizar una secuencia de arrastre
Después de definir los atributos draggable="true"
en tu contenido, adjunta un
Controlador de eventos dragstart
para iniciar la secuencia de arrastre de cada columna.
Este código establece la opacidad de la columna en un 40% cuando el usuario comienza a arrastrarla y lo volverá al 100% cuando finalice el evento de arrastre.
function handleDragStart(e) {
this.style.opacity = '0.4';
}
function handleDragEnd(e) {
this.style.opacity = '1';
}
let items = document.querySelectorAll('.container .box');
items.forEach(function (item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragend', handleDragEnd);
});
El resultado se puede ver en la siguiente demostración de Glitch. Arrastrar un elemento y sus
cambia la opacidad. Como el elemento de origen tiene el evento dragstart
, establecer
El porcentaje de this.style.opacity
al 40% le indica al usuario que el elemento se
se está moviendo la selección actual. Cuando sueltas el elemento, el elemento de origen
vuelve al 100% de opacidad, incluso si aún no definiste el comportamiento de la acción de soltar.
Agrega señales visuales adicionales
Para ayudar al usuario a entender cómo interactuar con tu interfaz, usa el
Controladores de eventos dragenter
, dragover
y dragleave
. En este ejemplo,
las columnas son objetivos para soltar, además de arrastrarse. Ayuda al usuario a
entender esto haciendo que el borde sea discontinuo cuando sostienen un elemento arrastrado sobre un
. Por ejemplo, en tu CSS, puedes crear una clase over
para
elementos que son destinos para soltar:
.box.over {
border: 3px dotted #666;
}
Luego, en tu JavaScript, configura los controladores de eventos, agrega la clase over
cuando
la columna se arrastra y se la quita cuando sale el elemento arrastrado. En
dragend
, también nos aseguramos de quitar las clases al final de la
arrastrar.
document.addEventListener('DOMContentLoaded', (event) => {
function handleDragStart(e) {
this.style.opacity = '0.4';
}
function handleDragEnd(e) {
this.style.opacity = '1';
items.forEach(function (item) {
item.classList.remove('over');
});
}
function handleDragOver(e) {
e.preventDefault();
return false;
}
function handleDragEnter(e) {
this.classList.add('over');
}
function handleDragLeave(e) {
this.classList.remove('over');
}
let items = document.querySelectorAll('.container .box');
items.forEach(function(item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragover', handleDragOver);
item.addEventListener('dragenter', handleDragEnter);
item.addEventListener('dragleave', handleDragLeave);
item.addEventListener('dragend', handleDragEnd);
item.addEventListener('drop', handleDrop);
});
});
Hay un par de puntos que vale la pena cubrir en este código:
La acción predeterminada del evento
dragover
es establecer la propiedaddataTransfer.dropEffect
en"none"
La propiedaddropEffect
se analiza más adelante en esta página. Por ahora, solo debes saber que evita que se active el eventodrop
. Para anular esto nuevo, llama ae.preventDefault()
. Otra práctica recomendada es devolverfalse
en ese mismo controlador.El controlador de eventos
dragenter
se usa para activar o desactivar la claseover
en lugar dedragover
Si usasdragover
, el evento se activa repetidamente mientras el usuario. Contiene el elemento arrastrado sobre una columna, lo que hace que la clase de CSS active o desactive repetidamente. Esto hace que el navegador realice muchos trabajos de renderización innecesarios lo que puede afectar la experiencia del usuario. Recomendamos minimizar se vuelve a dibujar y, si necesitas usardragover
, considera restringir o anular el efecto de un objeto de escucha de eventos.
Completa la acción de soltar
Para procesar la acción de soltar, agrega un objeto de escucha de eventos para el evento drop
. En drop
del navegador, deberás evitar que se aplique el comportamiento predeterminado del navegador
suele ser algún tipo de redireccionamiento molesto. Para ello, llama a e.stopPropagation()
.
function handleDrop(e) {
e.stopPropagation(); // stops the browser from redirecting.
return false;
}
Asegúrate de registrar el nuevo controlador junto con los otros controladores:
let items = document.querySelectorAll('.container .box');
items.forEach(function(item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragover', handleDragOver);
item.addEventListener('dragenter', handleDragEnter);
item.addEventListener('dragleave', handleDragLeave);
item.addEventListener('dragend', handleDragEnd);
item.addEventListener('drop', handleDrop);
});
Si ejecutas el código en este punto, el elemento no cae en la nueva ubicación. Para
haz que eso suceda, usa DataTransfer
.
La propiedad dataTransfer
contiene los datos enviados en una acción de arrastre. dataTransfer
Se establece en el evento dragstart
y se lee o controla en el evento de soltar. Llamando
e.dataTransfer.setData(mimeType, dataPayload)
te permite establecer el MIME del objeto.
y la carga útil de datos.
En este ejemplo, vamos a permitir que los usuarios reorganicen el orden de las columnas. Para ello, primero debes almacenar el código HTML del elemento de origen cuando se arrastra comienza:
function handleDragStart(e) {
this.style.opacity = '0.4';
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
En el evento drop
, debes procesar el lanzamiento de columnas mediante la configuración del valor de
HTML en el HTML de la columna de destino en la que colocaste los datos Esta
incluye comprobar que el usuario no vuelva a la misma columna
desde donde se arrastre.
function handleDrop(e) {
e.stopPropagation();
if (dragSrcEl !== this) {
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
return false;
}
Puedes ver el resultado en la siguiente demostración. Para que esto funcione, necesitarás una navegador para computadoras de escritorio. La API de arrastrar y soltar no es compatible con dispositivos móviles. Arrastrar y libera la columna A sobre la columna B y observa cómo cambian de lugar:
Más propiedades de arrastre
El objeto dataTransfer
expone propiedades para brindar información visual al
usuario durante el proceso de arrastre y controlar la forma en que cada destino para soltar responde a una
tipo de datos determinado.
dataTransfer.effectAllowed
restringe qué 'tipo de arrastre' que el usuario puede realizar en el elemento. Se usa en el modelo de procesamiento de arrastrar y soltar para inicializardropEffect
durante los eventosdragenter
ydragover
La propiedad puede tener la los siguientes valores:none
,copy
,copyLink
,copyMove
,link
,linkMove
,move
,all
yuninitialized
.dataTransfer.dropEffect
controla los comentarios que recibe el usuario durante las fasesdragenter
ydragover
eventos. Cuando el usuario mantiene el puntero sobre un elemento de destino, la ventana el cursor indica qué tipo de operación se llevará a cabo, como una copia o una mudanza. El efecto puede tener uno de los siguientes valores:none
,copy
,link
,move
e.dataTransfer.setDragImage(imgElement, x, y)
significa que, en vez de utilizar la "imagen fantasma" predeterminada del navegador, comentarios, tú puedes establecer un ícono de arrastrar.
Subir archivo
En este ejemplo simple, se usa una columna como fuente y destino de arrastre. Esta puede suceder en una IU que le pida al usuario que reorganice los elementos. En algunas situaciones, el destino de arrastre y el origen pueden ser de diferentes tipos de elementos, como en una interfaz en el que el usuario debe seleccionar una imagen como imagen principal de un producto arrastrando la imagen seleccionada a un objetivo.
La función de arrastrar y soltar se usa con frecuencia para permitir que los usuarios arrastren elementos de su escritorio a
de una aplicación. La diferencia principal está en tu controlador drop
. En lugar de usar
dataTransfer.getData()
para acceder a los archivos; sus datos se encuentran en
Propiedad dataTransfer.files
:
function handleDrop(e) {
e.stopPropagation(); // Stops some browsers from redirecting.
e.preventDefault();
var files = e.dataTransfer.files;
for (var i = 0, f; (f = files[i]); i++) {
// Read the File objects in this FileList.
}
}
Puedes encontrar más información sobre este tema en Función de arrastrar y soltar personalizada: