HTML5.3 § 5.7. Drag and Drop

Drag and drop

Vediamo come le specifiche di html presentano il drag and drop.

HTML5 definisce un meccanismo di trascinamento e rilascio di elementi selezionati basato su eventi. Tipicamente questa operazione è realizzata utilizzando un mouse o un altro dispositivo di puntamento, ma si potrebbe pensare anche a modalità di input diverse secondo le quali gli utenti possano avviare la procedura, indicare la selezione ed il punto di rilascio.

Ad ogni modo, qualunque sia l'implementazione, le operazioni di di trascinamento e rilascio devono avere:

  1. un punto di partenza (click del mouse o inizio della selezione degli elementi da trascinare);
  2. un numero qualsiasi di passaggi intermedi(passaggio sopra i possibili elementi di rilascio o altra modalità di scelta delle possibili destinazioni) ;
  3. un punto finale di rilascio;(in cui si solleva il pulsante del mouse, o che è stato scelto con altra modalità)
  4. la possibilità di annullare l'operazione in qualsiasi momento.

Il punto finale deve essere l'ultimo elemento selezionato come possibile elemento di rilascio prima che si verifichi il rilascio. Quindi se l'operazione non viene annullata, deve esserci almeno un passaggio sopra o una scelta di un elemento di destinazione.

Esempio 2 (da HTML5.3 §5.7. Drag and Drop)

Rendere un elemento trascinabile è semplice: assegnare ad esso l'attributo draggable, impostare un gestore per l'evento dragstart che memorizza i dati trascinati.

In generale il gestore di dragstart deve verificare che non sia una selezione di testo quella che viene trascinata, deve memorizzare i dati selezionati nell'oggetto DataTransfer, e deve impostare gli effetti consentiti (copia, spostamento, collegamento o una qualche combinazione di questi).

Per esempio:

What fruits do you like?

  1. Apples
  2. Oranges
  3. Pears

Drop your favorite fruits below:

     

Codice HTML

<div id="esempio1">
      <p>What fruits do you like?</p>
      <ol ondragstart="dragStartHandler(event)" ondragend="dragEndHandler(event)">
            <li draggable="true" data-fruit="fruit-apple">Apples</li>
            <li draggable="true" data-fruit="fruit-orange">Oranges</li>
            <li draggable="true" data-fruit="fruit-pear">Pears</li>
      </ol>  
      <p>Drop your favorite fruits below:</p>
      <ol ondragover="DragOver(event)" ondrop="dropHandler(event)">
            &nbsp;
      </ol>                     
</div>
Per far funzionare l'esempio ho dovuto fare qualche modifica al codice presentato nella specifica. Copiandolo così com'è non sono riuscito, forse per mie carenze, a farlo funzionare. Per prima cosa ho aggiunto un carattere &nbsp; sotto l'elemento ol di destinazione. Non è una soluzione corretta per HTML ma al momento non sono riuscito a trovare un'altra soluzione.
Inoltre per rendere compatibile il codice html con il gestore dell'evento drop ho dovuto aggiungere negli attributi li della lista di origine l'attributo custom data-fruit.

Attributi custom

l'attributo data-fruit degli elementi li è un attributo custom. Potrà essere recuperato successivamente mediante il metodo getAttribute("data-fruit").

Codice JavaScript


  // set this to something specific to your site
   var internalDNDType = 'text/x-example';

  function dragStartHandler(event) {
    if (event.target instanceof HTMLLIElement) {
      // use the element’s data-value="" attribute as the value to be moving:
      event.dataTransfer.setData(internalDNDType, event.target.dataset.fruit);
      // only allow moves
      event.dataTransfer.effectAllowed = 'move';
    } else {
      // don’t allow selection to be dragged
         event.preventDefault();
    }
  }
  function DragOver(event) {
      event.preventDefault();
  }
   function dropHandler(event) {
    var li = document.createElement('li');
    var data = event.dataTransfer.getData(internalDNDType);
    if (data == 'fruit-apple') {
      li.textContent = 'Apples';
    } else if (data == 'fruit-orange') {
      li.textContent = 'Oranges';
    } else if (data == 'fruit-pear') {
      li.textContent = 'Pears';
    } else {
      li.textContent = 'Unknown Fruit';
    }
    event.target.appendChild(li);
  }
  function dragEndHandler(event) {
    if (event.dataTransfer.dropEffect == 'move') {
      // remove the dragged element
      event.target.parentNode.removeChild(event.target);
    }
  }  

Oggetto DataTransfer

L'oggetto DataTransfer è usato per memorizzare i dati trascinati durante una operazione di drag and drop. Esso può contenere più item, ognuno dei quali di di più data types.

Questo oggetto è disponibile dalla property dataTransfer di tutti gli eventi drag. Esso non può essere creato separatamente (infatti non c'è costruttore per questo oggetto.