
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
topaleft.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
xaybude výsledná hodnota pro nastavení jakoleftatop(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.xasouradnice.ya 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
leftatopzajistit 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=ontouchstartonmousemove=ontouchmoveonmouseup=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].pageXevent.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
Související články
JavaScript null a undefined
Rozdíly mezi null a undefined v JavaScriptu, kdy je používat a jak se vyhnout běžným chybám.
Sleep v JavaScriptu
Jak implementovat sleep/delay funkcionalitu v JavaScriptu pomocí Promise a async/await
JavaScript Battery API
Jak v JS zjistit stav baterie, co dnes funguje a kdy API nepoužívat.