Drag & Drop v JavaScriptu
Jak vytvořit „drag & drop“ přesouvání prvků po stránce v JavaScriptu.
V některých situacích chceme uživateli umožnit přesun nějakého objektu po stránce.
Posun objektu v CSS
Před samotnou tvorbou JS přesouvání je nutné zvolit technické řešení přesunu v CSS. Nabízejí se dvě základní možnosti:
-
Elementu přidat relativní posici a měnit mu jeho hodnoty
top
aleft
.position: relative; left: posunX; top: posunY;
-
Přesouvat element CSS transformací.
transform: translate(posunX, posunY);
První způsob pomocí relativního posicování má prakticky 100% podporu napříč prohlížeči. Přesun transformací funguje od IE 9, ale umožní přesouvat bez řešení typu posice a hlavně je lépe optimalisovaný s ohledem na výkon.
Prohlížeče si pro elementy přesouvané pomocí transform: translate
vytvoří zvláštní vrstvu, což sníží náročnost na překreslování. U přesunu posicováním se musí změněná plocha v okolí přesouvaného elementu překreslovat, což u hodně komplikované stránky může znamenat pokles FPS (snímků za vteřinu).
Postup v JavaScriptu
-
Připravíme si přesouvatelný element a potřebné proměnné.
var presouvany = document.querySelector("#presouvany-element"); var souradnice = {x: 0, y: 0}; // výchozí relativní umístění var posunSouradnice; // pro zjišťování posunu var puvodniSouradnice; // souradnice prvku před posunem
-
Při události
onmousedown
(stisknutí tlačítka) se prvku, co má být možný přetahovat, přidá třída nebo vlastní atribut. Zároveň se do nějaké proměnné uloží relativní souřadnice prvku v době před posunem (při prvním přesunu to bude0;0
) a do další proměnné aktuální souřadnice kursoru.Aktuální souřadnice kursoru zjistíme například z
event.pageX
/event.pageY
.presouvany.setAttribute("data-move", ""); puvodniSouradnice = {x : souradnice.x, y: souradnice.y}; posunSouradnice = { x: event.pageX, y: event.pageY };
-
Následně se při posouvání myši v rámci dokumentu (
document.onmousemove
) zkontroluje přítomnost atributudata-move
– kladný výsledek znamená, že je co přesouvat, takže se začne s přesunem. Záporný výsledek potom znamená, že se nic dál dělat nebude (return
).if (!presouvany.hasAttribute("data-move")) return;
Na základě původních hodnot v proměnné
posunSouradnice
, se zjistí rozdíl oproti začátku posouvání. Který se přičte k aktuálním souřadnicím.var x = souradnice.x + event.pageX - posunSouradnice.x; var y = souradnice.y + event.pageY - posunSouradnice.y;
V proměnných
x
ay
bude výsledná hodnota pro nastavení jakoleft
atop
(nebo parametry protranslate
). Zde může proběhnout případná kontrola, zda člověk nepřesouvá do míst, kam nemá.Nyní stačí aktualisovat hodnoty
souradnice.x
asouradnice.y
a nastavit nový styl.souradnice.x = x; souradnice.y = y; presouvany.style.left = x + "px"; presouvany.style.top = y + "px";
Případně místo změny
left
atop
zajistit přesun pomocítransofrm
(je vhodné použít CSS prefixy:presouvany.style.transform = "translate(" + x + "px, " + y + "px)";
-
Při uvolnění tlačítka (
onmouseup
) odebereme přesouvací atribut, čímž se přesouvání ukončí.presouvany.removeAttribute("data-move");
-
Znázornit možnost přesouvání pomůže
cursor: move
.
Ukázka s využitím posicování / transformace
Dotyková zařízení
Pro dotyková zařízení je třeba nahradit události onmouse*
za ontouch*
.
onmousedown
=ontouchstart
onmousemove
=ontouchmove
onmouseup
=ontouchend
Asi největší odlišnost je v tom, že dotyková zařízení mohou umět více dotyků najednou. Zajímat nás bude ale nejspíš jen ten první, takže:
event.pageX
=event.touches[0].pageX
event.pageY
=event.touches[0].pageY
Odkazy jinam
- Chamurappiho přesouvání na 15 řádek
- Drag & Drop události myši – umožňují reagovat na přesunutí elementu na určité místo
Komentáře