6. Jun 2022Frontend

Ako jednoducho implementovať Drag and drop pomocou natívneho HTML API

V tomto článku sa venujem problematike “drag and dropu”, s ktorým sa v praxi určite stretol každý. Mnohí pri implementácii tejto funkcie siahnu po knižnici, čo je “jednoduchšie”. Nemusí to však platiť v každom prípade. Knižnice sú zvyčajne závislé od iných modulov, ktoré nepotrebujete, alebo je potrebné knižnicu upraviť, aby spĺňala požiadavky na funkčnosť.

Roman HaluškaFrontend developer

Pozrieme sa na to, aké natívne možnosti poskytuje samotný API interface HTML5 na implementáciu funkcie drag and drop.

Pomocou natívneho rozhrania HTML5 môžeme povoliť funkciu drag and drop v podstate pre akýkoľvek HTML element. Je to jednoduché, stačí pre daný elemnt nastaviť atribút draggable=true.

<div
	className={'drag-item-list'}
	key={item.label}
	draggable={true}
>
  <DragOutlined /> {item.label}
</div>

Priradením tohto atribútu je možné aktivovať funkciu drag and drop, napríklad pre tieto elemnty: obrázok, súbor, odkaz...

Ďalej sa pozrieme, aké callbacky poskytuje interface v prípade zmeny pozície presúvaného elementu.

Typy a spracovanie eventov

Natívny interface nám poskytuje množstvo rôznych eventov, ktoré môžeme použiť na monitorovanie a riadenie celého procesu drag and drop. Pomocou týchto eventov môžeme vykonávať potrebné operácie so zobrazenými dátami, s ktorými používateľ interaguje. Nižšie spomenieme vybrané udalosti, bez ktorých nie je možné túto funkciu používať.

event dragStartonDragStart

Tento event handler slúži pre spracovanie elementu, ktorý je aktuálne presúvaný a v príklade slúži na odoslanie dát.

Funkcia dataTransfer.setData() nastavuje typ údajov a hodnotu presunutých údajov.

onDragStart={(event) => {
  event.dataTransfer.setData('text', JSON.stringify({ label: 'test', value: '1' }))
}}

V tomto príklade je typ údajov text a hodnota objekt z atribútov label a value.

event droponDrop

Event handler onDrop poskytuje možnosť získať dáta o presunutom elemente do aktívnej drop zóny. Ako príklad môžeme uviesť jednoduchý zoznam, v ktorom by sa nachádzali rôzne druhy aktivít a používateľ by mal možnosť tieto prvky presúvať do drop zóny, kde by bolo následne možné meniť poradie aktivít zo zoznamu.

const onDrop = (event: any) => {
  try {
	// parse droped element data
	const data = JSON.parse(event.dataTransfer.getData('text'))
	addElement(data)
  } catch (error) {
	console.log(error)
  }
}

V príklade je uvedená funkcia onDrop, ktorá zabezpečuje získanie a spracovanie dát prvku vloženého do zoznamu aktivít. Pre získanie dát je potrebné zavolať metódu dataTransfer.getData('text') . Keďže v našom prípade sa jedná o objekt, tak si ho preparsujeme do JSON formátu a zavoláme funkciu na pridanie aktivity do zoznamu.

event dragOveronDragOver

Slúži na spracovanie eventu, ak presúvaný prvok "prejde" cez drop zónu. Ak používateľ element presúva cez aktívnu drop zónu, je potrebné zabrániť pridaniu elementu do drop zóny čo je predvolené správanie, a to zavolaním metód preventDefault() a stopPropagation() .

onDragOver={(event) => {
  event.preventDefault()
  event.stopPropagation()
}}

event dragLeaveonDragLeave

Tento event handler môžeme použiť na odstránenie prvku, ktorý aktuálne používateľ presúva, ale ešte ho "nepustil" do cieľovej drop zóny/elementu, prípadne pustil element mimo cieľovú zónu. Ako príklad uvediem presúvanie aktivity medzi jednotlivými stĺpcami, kde sa vyžaduje animácia odobratia presúvaného elmentu alebo animácia nad drop zónou.

event dragEnteronDragEnter

Handlerom monitorujeme element, ktorý používateľ presúva a ktorý vstúpil do ohraničenia drop zóny/elementu. Využitie má opačné ako onDragLeave, teda v prípade, že presúvaný element vstúpil do drop zóny, ale presúvanie nebolo ukončené drop akciou. Potom môžeme element pridať.

event dragendonDragEnd

Event je spustený, ak bol používateľom presúvaný element "položený" do drop zóny. Využitie je podobné ako pri evente onDragLeave.

Demonštrácia na príklade

Ako príklad som vybral jednoduchý list prvkov, ktorý bude umiestnený vľavo, a vpravo bude umiestnená drop zóna, do ktorej bude môcť používateľ pridávať jednotlivé elementy zo zoznamu.

Záver

Pevne verím, že som vám priblížil a objasnil možnosti využitia natívneho HTML API interface pre drag and drop. Ak sa opäť stretnete s požiadavkou implementovať túto funkcionalitu do vášho projektu, určite zvážte všetky pre a proti použitia knižnice, ktorá tieto možnosti poskytuje, alebo si zoberte riešenie z tohto článku🙂.

Roman HaluškaFrontend developer