Jak v HTML5 na drag&drop funkcionalitu

26. srpna 2013

Tento překladový článek od Sara Vieiry vám předvede, jak snadno lze v HTML5 se špetkou JavaScriptu implementovat drag&drop funkcionalitu.

Ačkoliv v JavaScriptu už dávno existují všelijaké funkce, které umožňují vytvořit rozhraní pro drag&drop funkcionalitu (táhni&pusť), žádnou z těchto implementací nešlo považovat za nativní z pohledu webového prohlížeče. V HTML5 to ovšem možné je – pochopitelně s drobnou výpomocí JavaScriptu – a tento článek vám ukáže, jak na to.

Podpora v prohlížečích

Než budeme pokračovat, chci, aby bylo jasno v jedné věci – současná metoda přetahování prvků myší je v HTML podporována všemi významnějšími desktopovými prohlížeči včetně IE (částečnou podporu poskytuje dokonce i IE 5.5), ale v současnosti není podporována žádným prohlížečem v mobilních telefonech.

Události pro přetahování myší

V každé fázi přetahování prvků prostřednictvím myši se odpalují různé události, které umožňují prohlížeči rozpoznat, který kód JavaScriptu má vlastně vykonat. Jedná se o tyto události:

  • dragStart: odpálí se, když uživatel začne přetahovat prvek.
  • dragEnter: odpálí se, když je přetahovaný prvek poprvé tažen přes cílový prvek.
  • dragOver: odpálí se, když se myš během přetahování posouvá přes prvek.
  • dragLeave: odpálí se, když kurzor uživatele při přetahování upustí prvek.
  • drag: odpálí se při každém pohybu myši během přetahování prvku.
  • drop: odpálí se, když je přetahovaný prvek upuštěn.
  • dragEnd: odpálí se, když uživatel během přetahování objektu uvolní myš.

Všechny tyto naslouchače událostí vám poskytují velkou kontrolu nad funkčností rozhraní a prováděním přetahování za různých okolností.

Objekt dataTransfer

Toto je místo, kde se odehrávají všechna ta přetahovací kouzla – tento objekt obsahuje data, která se mají přesunout. Data mohou být nastavena a vyvolána různými způsoby. Mezi ty nejdůležitější patří tyto:

  • dataTransfer.effectAllowed=value: vrací zpět povolené akce, možnými hodnotami jsou none, copy, copyLink, copyMove, link, linkMove, move, all a uninitialized.
  • dataTransfer.setData(format, data): přidává specifikovaná data a jejich formát.
  • dataTransfer.clearData( format ): odstraňuje data se specifikovaným formátem.
  • dataTransfer.setDragImage(element, x, y): nastavuje obrázek, který chcete přetahovat, hodnoty x a y určují, kde by měl být kurzor myši (hodnoty 0, 0 umístí kurzor do levého horního rohu).
  • data = dataTransfer.getData(format): jak je zřejmé z názvu, vrací zpět data dostupná pro specifikovaný formát.

Příklad přetahování

Nyní si vytvoříme jednoduchý příklad přetahování. Jak můžete z ukázky vidět, máme zde dva malé a jeden velký element; malé elementy můžete přetáhnout do velkého a můžete je dokonce i přetáhnout zpět.

Přetahování objektu

Nejprve musíte vytvořit odpovídající HTML kód. Prvku, který chceme nastavit jako přetahovatelný, specifikujeme atribut draggable:

<div id="boxA" draggable="true"></div>

Jakmile máme toto hotovo, musíme si nadefinovat JavaScriptovou funkci, jež se spustí, jakmile začneme prvek přetahovat:

function dragStart(ev) {
   ev.dataTransfer.effectAllowed='move';
   ev.dataTransfer.setData("Text", ev.target.getAttribute('id'));   ev.dataTransfer.setDragImage(ev.target,100,100);
   return true;
}

V tomto kódu prvně deklarujeme, jaký efekt chceme povolit, a říkáme, že příkazem move (na druhém řádku) nastavujeme data pro akci. V našem případě se jedná o Text, jehož hodnotou je ID prvku, který budeme přetahovat. Následně použijeme metodu setDragImage, kterou specifikujeme, co budeme přetahovat a kde se bude během přetahování nacházet kurzor. Protože budeme přetahovat čtverce o rozměrech 200×200 px, umístil jsem je do středu. Na konci kódu vrátíme true.

Upuštění objektu

Aby mohl být prvek upuštěn, potřebujeme naslouchat třem různým akcím: dragEnter, dragOver a také drop. Přidáme je do našeho prvku div s ID big.

<div id="big" ondragenter="return dragEnter(event)" ondrop="return dragDrop(event)" ondragover="return dragOver(event)"></div>

V tento okamžik máme přidané naslouchače událostí a nyní musíme vytvořit následující funkce, které spustíme akcemi dragenter a dragover:

function dragEnter(ev) {
   ev.preventDefault();
   return true;
}
function dragOver(ev) {
    ev.preventDefault();
}

U první funkce definujeme, co chceme, aby se událo ve chvíli, kdy přetahovaný prvek dosáhne prvku, na který má být upuštěn – v tomto případě pouze předcházíme výchozímu chování prohlížeče, vy však můžete provést množství dalších akci, například můžete změnit pozadí či přidat nějaký text pro lepší indikaci toho, že uživatel přetahuje správnou oblast, a použít akci dragleave, která vám umožní vrátit zpět provedené změny. Funkcí dragOver pak předcházíme výchozímu chování souvisejícím s upuštěním.

V následující části definujeme funkci, kterou skutečně upustíme prvek na požadovaný cíl:

function dragDrop(ev) {
   var data = ev.dataTransfer.getData("Text");
   ev.target.appendChild(document.getElementById(data));
   ev.stopPropagation();
   return false;
}

V této poslední části kódu JavaScriptu nejprve nastavíme proměnlivou data, kam uložíme veškerá dostupná data týkající se formátu textu a následně tato data (jež jsou přetahovaným prvkem) připojíme k prvku div, do něhož upustíme přetahovaný prvek. Na závěr přidáme stopPropagation a vrátíme false.

Vytváření cíle

Pokud si znovu prohlédnete náš příklad, povšimněte si, že jsme zajistili, aby se přetahované prvky mohly vrátit na své původní pozice. Naštěstí je přidání dalšího cíle pro upuštění přetahovaného prvku snadnější, než by se mohlo zdát – veškeré potřebné funkce už máme vytvořeny, takže je potřeba pouze přidat patřičné naslouchače událostí:

<section id="section" ondragenter="return dragEnter(event)" ondrop="return dragDrop(event)" ondragover="return dragOver(event)">

A to je všechno, co potřebujete, abyste umožnili přetažení prvku na jeho původní pozici.

Závěr

Ačkoliv dnes existuje nespočet aplikací k přetahování prvků využívajících všelijaké JavaScriptové knihovny (přičemž použití těchto knihoven je velice jednoduché), osobně doufám, že v této technice, která využívá HTML5 a JavaScript, objevíte kouzlo nativních řešení.

About translation

Language of translation: Czech (for readers from Czech and Slovak republics). Translated with the permission of Webdesigner Depot. Other translations.

Mohlo by vás také zajímat

Nejnovější

3 komentářů

  1. Mareg

    Zář 3, 2013 v 9:26

    Zdravím.
    Docela slušný strojový překlad, jen byste ve slovníku mohli upravit např. výrazy „odpálí se“, nebo „naslouchače“. Myslím, že existují přijatelnější české termíny.
    I popis „když je přetahovaný prvek poprvé tažen přes cílový prvek“ považuji za drobně matoucí.

    Ale i přesto děkuji za článek.

    Mareg

    Odpovědět
  2. Miroslav Kučera

    Zář 4, 2013 v 10:34

    Co vím, události v JavaScriptu se „odpalují“ odjakživa a „naslouchače“ (událostí) je také docela běžné spojení. Mně osobně překlad těchto dvou termínů připadá velice výstižný a srozumitelný. Ale mohu se samozřejmě mýlit. Jaké termíny byste použil vy?

    Odpovědět
  3. korem

    Úno 16, 2014 v 22:14

    JavaScript mi přijde jako jeden z nejlepších jazyků, nejen srozumitelně, ale i v rámci nějakýho uplatnění. A nejlépe uplatnění v cizině. Zkoušel jsem najít nějaké weby, které se tím specializují, nevíte nějaké osvědčené? Mě říkal kámoš o itprace-nemecko.cz/,prý mu tam sehnali nějakou práci, akorát jsem se ještě nedostal k tomu, abych tam napsal životopis… :D (snad neva ten odkaz, nemyslel jsem to jako spam, spíš jestli s touhle konkrétní firmou má někdo nějaké zkušenosti)

    Odpovědět

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *