Při webovém vývoji se někdy hodí umožnit uživateli uchopit nějakou položku myší a přemístit jí někam jinam. Na tuto funkcionalitu jsme si u webů celkem zvykli. Například se s ní setkáváme u e-mailových účtů, u nákupních košíků v e-shopech, u konfigurace vzhledu stránky atd.
"Drag and Drop" lze využít například při řazení seznamu položek v tabulce. Uživatel si může myší položky uspořádat a tak si přednastavit jak se mu budou zobrazovat. Starší příklad pro třídění položek tabulky pomocí jQuery a TableDnD pluginu nalezneme například na této stránce.
Jinak pokud používáme jQuery, můžeme pro implementaci Drag&Drop využít jQueryUI pluginy.
http://docs.jquery.com/UI/Droppable
http://docs.jquery.com/UI/Draggable
http://jqueryui.com/demos/draggable/
http://jqueryui.com/demos/draggable/#sortable
V HTML 5 je Drag and Drop podporováno pomocí atributu "draggable". Pomocí tohoto atributu označíme elementy, které lze přesouvat. Dále pak pomocí atributů "ondragenter", "ondragover", "ondrop", "ondragstart", "ondragend" definujeme obsluhu jednotlivých událostí. (Tyto atributy navážeme na funkce v JavaScriptu.)
ondragstart - nastane ve chvíli, kdy začneme element přesouvat (týká se taženého elementu)
ondragenter - nastane pokud vstoupí element nad cílový element (týká se cílového elementu)
ondragover - nastane pokud je element nad cílovým elementem (týká se cílového elementu)
ondrop - pokud upustíme element nad cílovým elementem (týká se cílového elementu)
ondragend - nastane pokud element přestaneme přemisťovat (týká se taženého elementu)
Pokud tedy píšeme kód stránky, budeme u elementů, které umožníme přesouvat, definovat atributy draggable, ondragstart, ondragend.
U cílových elementů definujeme ondragenter, ondragover, ondrop.
Velmi důležitý pro Drag & Drop je dataTransfer objekt. Dostaneme se k něme přes objekt události. Nastavujeme na něm, jaký efekt je povolen, jaká data přenášíme, jaká bude podoba přenášeného elementu ( obrázek ). Podrobný popis lze nalézt ve specifikaci pro Drag and drop.
Příklad:
Pro zajímavost jsem připravil malý příklad. Doporučuji spustit v poslední verzi prohlížeče Firefox.
Abych demonstroval možnosti Drag&Drop, doporučuji vyzkoušet přetáhnout na velký čtverec modrý čtvereček (má atribut draggable), výběr textu nad čtverci, odkaz nad čtverci, ale také výběr textu ze stránky v okně jiného prohlížeče a nebo dokonce soubor z plochy.
<!DOCTYPE HTML>
<html>
<head><title>HTML 5 Drag&Drop</title>
<style type="text/css">
div { border: 2px solid black;}
.prenos { width: 50px;height: 50px;background-color: blue;}
.kontejner {width: 200px;height: 200px;}
</style>
<script type="text/javascript">
var dndTyp = "text/x-test";
function zacatek(e)
{
e.dataTransfer.effectAllowed='move';
e.dataTransfer.setData(dndTyp,e.target.getAttribute('id'));
return true;
}
function nad(e){ return false; }
function polozeno(e)
{ var id_prenaseny = e.dataTransfer.getData(dndTyp);
var text = e.dataTransfer.getData("Text");
var files = e.dataTransfer.files;
if(id_prenaseny) {
e.target.appendChild(document.getElementById(id_prenaseny));
} else if(text) {
e.target.innerHTML = text;
} else if(files[0]) {
e.target.innerHTML = "File name :" + files[0].name + "<br/>Velikost :" + files[0].size;
}
return false;
}
function konec(e) { return true; }
function vstup(e) { return true; }
</script>
</head>
<body>
pokus pokus pokus<br/>
<a id="odkaz" href="http://www.novinky.cz">www.novinky.cz</a>
<br/>
<div id="box1" class="kontejner" ondragenter="return vstup(event)" ondragover="return nad(event)" ondrop="return polozeno(event)">
<div id="prenos1" class="prenos" draggable="true" ondragstart="return zacatek(event)" ondragend="return konec(event)">ABC</div>
</div>
<div id="box2" class="kontejner" ondragenter="return vstup(event)" ondragover="return nad(event)" ondrop="return polozeno(event)"></div>
</body>
</html>
Komentář k příkladu:
Odkazy a text sami podporují drag&drop. Div element s id prenos1 má nastavený atribut draggable na true a tím umožňuje přetahování myší u prohlížečů, které již atribut podporují.
Funkce zacatek nastavuje jako přenášená data u event.dataTransfer na id atribut taženého elementu.
Funkce polozeno načítá námi nadefinovaný typ dndTyp, pokud existuje. Pokud ne, pokusí se načíst výchozí typ Text, který použijeme při přenesení odkazu nebo textu. Pokud ani text není nastaven, pokouším se v kódu přistoupit na přenášený soubor a vypsat jeho jméno a velikost.
Div elementy s id box1 a box2 jsou tedy cílové elementy, na které můžeme přetahovat jiné položky jako například soubor z plochy, odkaz, text nebo i modrý div.
Podpora v prohlížečích:
Jak jsem uvedl, příklad je testován v poslední verzi Firefoxu. Relativně pokročilá je podpora u Safari. Horší je to u IE a u Opery. Situaci je možné opět monitorovat na následující stránce. ( Global - draggable a APIs - Drag-and-drop )
Odkazy:
http://zdrojak.root.cz/clanky/webdesigneruv-pruvodce-po-html5-tahni-a-srustej/