A continuación se describen los pasos que ocurren durante una operación de arrastrar y soltar.
Las operaciones de arrastre descritas en este documento utilizan la DataTransfer
interfaz. Este documento no no utilizar el DataTransferItem
interfaz ni el DataTransferItemList
interfaz.
los draggable
Atributo
En una página web, hay ciertos casos en los que se utiliza un comportamiento de arrastre predeterminado. Estos incluyen selecciones de texto, imágenes y enlaces. Cuando se arrastra una imagen o enlace, la URL de la imagen o enlace se establece como datos de arrastre y comienza un arrastre. Para otros elementos, deben ser parte de una selección para que ocurra un arrastre predeterminado. Para ver esto en efecto, seleccione un área de una página web y luego haga clic y mantenga presionado el mouse y arrastre la selección. Aparecerá una representación específica del sistema operativo de la selección y seguirá el puntero del mouse mientras se realiza el arrastre. Sin embargo, este comportamiento es solo el comportamiento de arrastre predeterminado, si ningún oyente ajusta los datos que se van a arrastrar.
En HTML, aparte del comportamiento predeterminado para imágenes, enlaces y selecciones, ningún otro elemento se puede arrastrar de forma predeterminada.
Para hacer que otros elementos HTML se puedan arrastrar, se deben hacer tres cosas:
- Selecciona el
draggable
= "true"
en el elemento que desea hacer arrastrable. - Agregue un oyente para el
evento.dragstart
-
Configure los datos de arrastre en el oyente anterior.
A continuación se muestra un ejemplo que permite arrastrar una sección de contenido.
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')"> This text <strong>may</strong> be dragged. </p>
los
el atributo está establecido en draggable
"true"
, por lo que este elemento se puede arrastrar. Si este atributo se omitió o se estableció en "false"
, el elemento no se arrastraría, sino que se seleccionaría el texto.
los
El atributo se puede utilizar en cualquier elemento, incluidas imágenes y enlaces. Sin embargo, para estos dos últimos, el valor predeterminado es draggable
true
, por lo que solo usaría el
atributo con un valor de draggable
false
para deshabilitar el arrastre de estos elementos.
Nota: Cuando un elemento se puede arrastrar, el texto u otros elementos dentro de él ya no se pueden seleccionar de la manera normal haciendo clic y arrastrando con el mouse. En cambio, el usuario debe mantener presionada la tecla Alt para seleccionar texto con el mouse o usar el teclado.
Inicio de una operación de arrastre
En este ejemplo, se agrega un oyente para el dragstart
evento usando el
atributo.ondragstart
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')"> This text <strong>may</strong> be dragged. </p>
Cuando un usuario comienza a arrastrar, el dragstart
se dispara el evento.
En este ejemplo el dragstart
El oyente se agrega al propio elemento arrastrable. sin embargo, podría escuchar a un antepasado superior a medida que surgen eventos de arrastre como lo hacen la mayoría de los demás eventos.
Dentro de dragstart
evento, puede especificar el arrastrar datos, los imagen de retroalimentación, y el efectos de arrastre, todos los cuales se describen a continuación. Sin embargo, solo el arrastrar datos es requerido. (La imagen predeterminada y los efectos de arrastre son adecuados en la mayoría de situaciones).
Arrastrar datos
Todos drag events
tener una propiedad llamada dataTransfer
que contiene los datos de arrastredataTransfer
es un DataTransfer
objeto).
Cuando ocurre un arrastre, los datos deben estar asociados con el arrastre que identifica qué está siendo arrastrado. Por ejemplo, al arrastrar el texto seleccionado dentro de un cuadro de texto, los datos asociados con el arrastrar elemento de datos es el texto en sí. De manera similar, al arrastrar un enlace en una página web, el elemento de datos de arrastre es la URL del enlace.
los drag data
contiene dos piezas de información, la escribe (o formato) de los datos, y la valor. El formato es una cadena de tipo (como text/plain
para datos de texto) y el valor es una cadena de texto. Cuando comienza el arrastre, agrega datos proporcionando un tipo y los datos. Durante el arrastre, en un detector de eventos para el
y dragenter
eventos, utiliza los tipos de datos de los datos que se arrastran para comprobar si se permite una caída. Por ejemplo, un destino para soltar que acepta enlaces buscaría el tipo dragover
text/uri-list
. Durante un evento de caída, un oyente recuperaría los datos que se estaban arrastrando y los insertaría en la ubicación de colocación.
los drag data's
types
propiedad devuelve una lista de tipo MIME como DOMString
s, como text/plain
o image/jpeg
. También puede crear sus propios tipos. Los tipos más utilizados se enumeran en el artículo Tipos de arrastre recomendados.
Un arrastre puede incluir elementos de datos de varios tipos diferentes. Esto permite que los datos se proporcionen en tipos más específicos, a menudo tipos personalizados, y aún así proporcionar datos de respaldo para destinos de colocación que no admiten tipos más específicos. Suele darse el caso de que el tipo menos específico sean los datos de texto normales que utilizan el tipo text/plain
. Estos datos serán una simple representación textual.
Para establecer un elemento de datos de arrastre dentro del dataTransfer
, utilizar el setData()
método. Toma dos argumentos: el tipo de datos y el valor de los datos. Por ejemplo:
event.dataTransfer.setData("text/plain", "Text to drag");
En este caso, el valor de los datos es “Texto para arrastrar” y tiene el formato text/plain
.
Puede proporcionar datos en varios formatos. Para hacer esto, llame al setData()
método varias veces con diferentes formatos. Debe llamarlo con formatos en orden del más específico al menos específico.
const dt = event.dataTransfer; dt.setData("application/x.bookmark", bookmarkString); dt.setData("text/uri-list", "https://www.mozilla.org"); dt.setData("text/plain", "https://www.mozilla.org");
Aquí, los datos se agregan en tres tipos diferentes. El primer tipo, application/x.bookmark
, es un tipo personalizado. Otras aplicaciones no admitirán este tipo, pero puede usar un tipo personalizado para arrastrar entre áreas del mismo sitio o aplicación.
Al proporcionar datos en otros tipos también, también podemos admitir arrastres a otras aplicaciones en formas menos específicas. los application/x.bookmark
type puede proporcionar datos con más detalles para su uso dentro de la aplicación, mientras que los otros tipos pueden incluir una única URL o versión de texto.
Tenga en cuenta que tanto el text/uri-list
y text/plain
contienen los mismos datos en este ejemplo. Esto a menudo será cierto, pero no tiene por qué ser así.
Si intenta agregar datos dos veces con el mismo formato, los datos nuevos reemplazarán a los datos antiguos, pero en la misma posición dentro de la lista de tipos que los datos antiguos.
Puede borrar los datos utilizando el clearData()
método, que toma un argumento: el tipo de datos que se eliminarán.
event.dataTransfer.clearData("text/uri-list");
los type
argumento a la clearData()
el método es opcional. Si el type
no se especifica, se eliminan los datos asociados con todos los tipos. Si el arrastre no contiene elementos de datos de arrastre, o si todos los elementos se borraron posteriormente, no se producirá ningún arrastre.
Configuración de la imagen de retroalimentación de arrastre
Cuando se produce un arrastre, se genera una imagen translúcida a partir del objetivo de arrastre (el elemento “dragstart
“al que se dispara el evento) y sigue el puntero del usuario durante el arrastre. Esta imagen se crea automáticamente, por lo que no es necesario que la cree usted mismo. Sin embargo, puede usar setDragImage()
para especificar una imagen de retroalimentación de arrastre personalizada.
event.dataTransfer.setDragImage(image, xOffset, yOffset);
Son necesarios tres argumentos. El primero es una referencia a una imagen. Esta referencia será típicamente a un <img>
elemento, pero también puede ser a un <canvas>
o cualquier otro elemento. La imagen de retroalimentación se generará a partir del aspecto que tenga la imagen en la pantalla, aunque en el caso de las imágenes, se dibujarán en su tamaño original. El segundo y tercer argumentos a la setDragImage()
El método son compensaciones donde la imagen debería aparecer en relación con el puntero del mouse.
También es posible utilizar imágenes y lienzos que no están en un documento. Esta técnica es útil cuando se dibujan imágenes de arrastre personalizadas utilizando el elemento canvas, como en el siguiente ejemplo:
function dragWithCustomImage(event) { const canvas = document.createElement("canvas"); canvas.width = canvas.height = 50; const ctx = canvas.getContext("2d"); ctx.lineWidth = 4; ctx.moveTo(0, 0); ctx.lineTo(50, 50); ctx.moveTo(0, 50); ctx.lineTo(50, 0); ctx.stroke(); const dt = event.dataTransfer; dt.setData('text/plain', 'Data to Drag'); dt.setDragImage(canvas, 25, 25); }
En este ejemplo, hacemos de un lienzo la imagen de arrastre. Como el lienzo es 50
×50
píxeles, usamos compensaciones de la mitad de esto (25
) para que la imagen aparezca centrada en el puntero del mouse.
Efectos de arrastre
Al arrastrar, hay varias operaciones que se pueden realizar. los copy
La operación se utiliza para indicar que los datos que se arrastran se copiarán desde su ubicación actual a la ubicación de colocación. los move
La operación se utiliza para indicar que los datos que se arrastran se moverán, y la link
La operación se utiliza para indicar que se creará alguna forma de relación o conexión entre las ubicaciones de origen y de destino.
Puede especificar cuál de las tres operaciones está permitida para una fuente de arrastre configurando el effectAllowed
propiedad dentro de una
oyente de eventos.dragstart
event.dataTransfer.effectAllowed = "copy";
En este ejemplo, solo un Copiar esta permitido.
Puede combinar los valores de varias formas:
none
- no se permite ninguna operación
copy
-
copy
solamente move
-
move
solamente link
-
link
solamente copyMove
-
copy
omove
solamente copyLink
-
copy
olink
solamente linkMove
-
link
omove
solamente all
-
copy
,move
, olink
- no inicializado
- El valor predeterminado es
all
.
Tenga en cuenta que estos valores deben usarse exactamente como se enumeran anteriormente. Por ejemplo, configurar el effectAllowed
propiedad a copyMove
permite una operación de copiar o mover, pero evita que el usuario realice una operación de enlace. Si no cambia el effectAllowed
propiedad, entonces se permite cualquier operación, al igual que con el ‘all
‘ valor. Por lo tanto, no necesita ajustar esta propiedad a menos que desee excluir tipos específicos.
Durante una operación de arrastre, un oyente del
o dragenter
los eventos pueden comprobar el dragover
effectAllowed
propiedad para ver qué operaciones están permitidas. Una propiedad relacionada, dropEffect
, debe establecerse dentro de uno de estos eventos para especificar qué operación única debe realizarse. Valores válidos para dropEffect
están none
, copy
, move
, o link
. Los valores de combinación no se utilizan para esta propiedad.
Con el
y dragenter
evento, el dragover
dropEffect
La propiedad se inicializa al efecto que el usuario está solicitando. El usuario puede modificar el efecto deseado presionando las teclas modificadoras. Aunque las claves exactas utilizadas varían según la plataforma, normalmente el Cambio y Control las teclas se utilizarían para alternar entre copiar, mover y vincular. El puntero del mouse cambiará para indicar qué operación se desea. Por ejemplo, para un copy
, el cursor puede aparecer con un signo más al lado.
Puede modificar el dropEffect
propiedad durante el
o dragenter
eventos, si, por ejemplo, un destino de colocación en particular solo admite ciertas operaciones. Puede modificar el dragover
dropEffect
propiedad para anular el efecto de usuario y hacer cumplir una operación de caída específica para que se produzca. Tenga en cuenta que este efecto debe estar incluido en el effectAllowed
propiedad. De lo contrario, se establecerá en un valor alternativo permitido.
event.dataTransfer.dropEffect = "copy";
En este ejemplo, copiar es el efecto que se realiza.
Puedes usar el valor none
para indicar que no se permite dejar caer en esta ubicación, aunque se prefiere no cancelar el evento en este caso.
Dentro de
y drop
eventos, puede consultar el dragend
dropEffect
propiedad para determinar qué efecto se eligió en última instancia. Si el efecto elegido fuera “move
“, los datos originales deben eliminarse del origen del arrastre dentro del
evento.dragend
Especificación de destinos de caída
Un oyente de la
y dragenter
Los eventos se utilizan para indicar destinos de colocación válidos, es decir, lugares donde se pueden soltar elementos arrastrados. La mayoría de las áreas de una página web o aplicación no lugares válidos para soltar datos. Por lo tanto, el manejo predeterminado de estos eventos es no permitir una caída.dragover
Si desea permitir una caída, debe evitar el manejo predeterminado cancelando tanto el dragenter
y dragover
eventos. Puede hacer esto regresando false
desde oyentes de eventos definidos por atributos, o llamando al evento preventDefault()
método. Esto último puede ser más factible en una función definida en un script separado.
<div ondragover="return false"> <div ondragover="event.preventDefault()">
Llamando al preventDefault()
método durante un
y dragenter
El evento indicará que se permite una caída en esa ubicación. Sin embargo, normalmente deseará llamar al dragover
preventDefault()
método solo en determinadas situaciones (por ejemplo, solo si se arrastra un enlace).
Para hacer esto, llame a una función que verifica una condición y solo cancela el evento cuando se cumple la condición. Si no se cumple la condición, no cancele el evento y no se producirá una caída allí si el usuario suelta el botón del mouse.
Es más común aceptar o rechazar una gota según el tipo de datos de arrastre en la transferencia de datos, por ejemplo, permitir imágenes, enlaces o ambos. Para hacer esto, puede verificar el types
propiedad del evento dataTransfer
(propiedad). los types
La propiedad devuelve una matriz de los tipos de cadenas que se agregaron cuando comenzó el arrastre, en el orden del más significativo al menos significativo.
function doDragOver(event) { const isLink = event.dataTransfer.types.includes("text/uri-list"); if (isLink) { event.preventDefault(); } }
En este ejemplo, usamos el includes
método para comprobar si el tipo text/uri-list
está presente en la lista de tipos. Si es así, cancelaremos el evento para que se permita una entrega. Si los datos de arrastre no contienen un enlace, el evento no se cancelará y no se podrá soltar en esa ubicación.
Es posible que también desee configurar el effectAllowed
, dropEffect
propiedad, o ambos al mismo tiempo, si desea ser más específico sobre el tipo de operación que se realizará. Naturalmente, cambiar cualquiera de las propiedades no tendrá ningún efecto si no cancela el evento también.
Dejar comentarios
Hay varias formas en las que puede indicarle al usuario que se permite una entrega en una ubicación determinada. El puntero del mouse se actualizará según sea necesario dependiendo del valor de la dropEffect
propiedad.
Aunque la apariencia exacta depende de la plataforma del usuario, normalmente aparecerá un icono de signo más para un ‘copy
‘por ejemplo, y aparecerá un icono de’ no se puede colocar aquí ‘cuando no se permita una gota. Esta retroalimentación del puntero del mouse es suficiente en muchos casos.
Sin embargo, también puede actualizar la interfaz de usuario con un punto de inserción o resaltar según sea necesario. Para un resaltado simple, puede usar el :-moz-drag-over
Pseudoclase CSS en un destino de colocación.
.droparea:-moz-drag-over { outline: 1px solid black; }
En este ejemplo, el elemento con la clase droparea
recibirá un contorno negro de 1 píxel mientras sea un destino de caída válido, es decir, si el preventDefault()
se llamó al método durante el
evento.dragenter
Nota: Debes cancelar el
evento para que se aplique esta pseudoclase, ya que este estado no se comprueba para el dragenter
evento.dragover
Para efectos visuales más complejos, también puede realizar otras operaciones durante la
evento. Por ejemplo, insertando un elemento en la ubicación donde ocurrirá la caída. Puede ser un marcador de inserción o un elemento que represente el elemento arrastrado en su nueva ubicación. Para hacer esto, puede crear un imagen o separador elemento e insértelo en el documento durante el dragenter
evento.dragenter
los
El evento disparará al elemento al que apunta el mouse. Naturalmente, es posible que deba mover el marcador de inserción alrededor de un dragover
evento también. Puedes usar el evento dragover
clientX
y clientY
propiedades como con otros eventos del mouse para determinar la ubicación del puntero del mouse.
Finalmente, el
El evento disparará a un elemento cuando el arrastre abandone el elemento. Este es el momento en el que debe eliminar cualquier marcador de inserción o resaltado. No es necesario cancelar este evento. Cualquier resaltado u otros efectos visuales especificados mediante el dragleave
:-moz-drag-over
La pseudoclase se eliminará automáticamente. los
El evento siempre se activará, incluso si se cancela el arrastre, por lo que siempre puede asegurarse de que se pueda realizar cualquier limpieza del punto de inserción durante este evento.dragleave
Realizar una gota
Cuando el usuario suelta el mouse, la operación de arrastrar y soltar termina.
Si se suelta el mouse sobre un elemento que es un destino de colocación válido, es decir, uno que canceló el último
o dragenter
evento, entonces la caída será exitosa, y un dragover
El evento disparará al objetivo. De lo contrario, la operación de arrastre se cancela y no drop
se dispara el evento.drop
Durante el
evento, debe recuperar los datos que se eliminaron del evento e insertarlos en la ubicación de entrega. Puedes usar el drop
dropEffect
propiedad para determinar qué operación de arrastre se deseaba.
Al igual que con todos los eventos relacionados con el arrastre, el evento
La propiedad contendrá los datos que se arrastran. los dataTransfer
getData()
El método puede usarse para recuperar los datos nuevamente.
function onDrop(event) { const data = event.dataTransfer.getData("text/plain"); event.target.textContent = data; event.preventDefault(); }
los getData()
El método toma un argumento, el tipo de datos a recuperar. Devolverá el valor de cadena que se estableció cuando setData()
fue llamado al comienzo de la operación de arrastre. Se devolverá una cadena vacía si no existen datos de ese tipo. (Naturalmente, sin embargo, probablemente sabrá que el tipo correcto de datos estaba disponible, ya que se verificó previamente durante una
evento.)dragover
En el ejemplo aquí, una vez que se han recuperado los datos, insertamos la cadena como el contenido textual del objetivo. Esto tiene el efecto de insertar el texto arrastrado donde se soltó, asumiendo que el destino de colocación es un área de texto como un p
o div
elemento.
En una página web, debe llamar al preventDefault()
método del evento si ha aceptado la caída, de modo que el manejo predeterminado del navegador no se active también por los datos descartados. Por ejemplo, cuando se arrastra un enlace a una página web, Firefox abrirá el enlace. Al cancelar el evento, se evitará este comportamiento.
También puede recuperar otros tipos de datos. Si los datos son un enlace, debe tener el tipo text/uri-list
. A continuación, puede insertar un enlace en el contenido.
function doDrop(event) { const lines = event.dataTransfer.getData("text/uri-list").split("n"); lines.filter(line => !line.startsWith("#")) .forEach(line => { const link = document.createElement("a"); link.href = line; link.textContent = line; event.target.appendChild(link); }) event.preventDefault(); }
Este ejemplo inserta un enlace de los datos arrastrados. Como su nombre lo indica, el text/uri-list
type en realidad puede contener una lista de URL, cada una en una línea separada. El código anterior utiliza split
para dividir la cadena en líneas, luego itera sobre la lista de líneas e inserta cada una como un enlace en el documento. (Tenga en cuenta también que los enlaces que comienzan con un signo de número (#
) se omiten, ya que son comentarios).
Para casos simples, puede utilizar el tipo especial URL
solo para recuperar la primera URL válida de la lista. Por ejemplo:
const link = event.dataTransfer.getData("URL");
Esto elimina la necesidad de buscar comentarios o iterar a través de las líneas usted mismo. Sin embargo, está limitado solo a la primera URL de la lista.
los URL
type es un tipo especial. Se usa solo como una abreviatura y no aparece dentro de la lista de tipos especificada en el types
propiedad.
A veces, puede admitir algunos formatos diferentes y desea recuperar los datos más específicos admitidos. En el siguiente ejemplo, un destino de colocación admite tres formatos.
El siguiente ejemplo devuelve los datos asociados con el formato mejor admitido:
function doDrop(event) { const supportedTypes = ["application/x-moz-file", "text/uri-list", "text/plain"]; const types = event.dataTransfer.types.filter(type => supportedTypes.includes(type)); if (types.length) { const data = event.dataTransfer.getData(types[0]); } event.preventDefault(); }
Terminando un arrastre
Una vez que se completa el arrastre,
El evento se dispara en la fuente del arrastre (el mismo elemento que recibió el dragend
evento). Este evento se disparará si el arrastre fue exitoso.[1] o si fue cancelado. Sin embargo, puede utilizar el dragstart
dropEffect
propiedad para determinar qué operación de caída ocurrió.
Si el dropEffect
la propiedad tiene el valor none
durante un
, luego se canceló el arrastre. De lo contrario, el efecto especifica qué operación se realizó. La fuente puede utilizar esta información después de una dragend
move
operación para eliminar el elemento arrastrado de la ubicación anterior. los mozUserCancelled
la propiedad se establecerá en true
si el usuario canceló el arrastre (presionando Escapar), y false
si el arrastre se canceló por otras razones, como un destino de colocación no válido, o si tuvo éxito.
Una caída puede ocurrir dentro de la misma ventana o sobre otra aplicación. los
el evento siempre se disparará independientemente. Los eventos dragend
screenX
y screenY
Las propiedades se establecerán en las coordenadas de la pantalla donde ocurrió la caída.
Después de la
el evento ha terminado de propagarse, la operación de arrastrar y soltar está completa.dragend
[1]: En Gecko, dragend
no se envía si el nodo de origen se mueve o elimina durante el arrastre (por ejemplo, al soltar o dragover
). Error 460801
Ver también
- API HTML de arrastrar y soltar (descripción general)
- Arrastrar y soltar varios elementos
- Tipos de arrastre recomendados
- Estándar de vida HTML5: arrastrar y soltar