React.js: implementujte funkciu drag and drop bez použitia externých knižníc

Zoznámte sa s podrobnosťami implementácie funkcií drag and drop v React od nuly.

Najprv sa pozrime na výsledok toho, čo budeme stavať. Skúšam .gif - dúfajme, že to bude fungovať všade podľa očakávaní. Používal som Camtasiu s osobným preukazom.

Kľúčovými bodmi učenia sú:

  1. urobte prvok presunutím pridaním atribútu „presunutie“
  2. urobte oblasť droppable implementáciou udalosti „dragover“
  3. zachytiť údaje o pretiahnutí implementáciou udalosti „dragstart“
  4. zachytiť pokles implementáciou udalosti „drop“
  5. implementovať udalosť „pretiahnutia“, ktorá sa spustí pri ťahaní prvku
  6. uložiť prechodné údaje v objekte dataTransfer

Pre študentov vizuálneho zamerania prejdite na video nižšie.

Krok 1 - vytvorte koreňovú aplikáciu pre ukážku

Celý kód pre drag and drop sa dostane do komponenty AppDragDropDemo.js.

import React from 'react';import ReactDOM from 'react-dom';import '.index.css';import AppDragDropDemo from './AppDragDropDemo';
ReactDOM.render(, document.getElementById("root"));

Vstupný bod pre AppDragDropDemo vyzerá ako kód uvedený nižšie.

import React, { Component } from 'react';
export default class AppDragDropDemo extends Component { render () { return ( DRAG & DROP DEMO ); }}

Ak teraz aplikáciu spustíte, zobrazí sa vám táto úžasná obrazovka (zamýšľaná hračka)

Krok 2 - vytvorte objekt stavu na uloženie niektorých úloh

Vytvorme niekoľko úloh na simuláciu jednoduchej aplikácie. To, čo chceme urobiť, je presunúť tieto úlohy do rôznych kategórií, ako wipcompleteatď.

export default class AppDragDropDemo extends Component { state = { tasks: [{name:"Learn Angular", category:"wip", bgcolor: "yellow"}, {name:"React", category:"wip", bgcolor:"pink"}, {name:"Vue", category:"complete", bgcolor:"skyblue"} ]}
 render () { return ( DRAG & DROP DEMO ); }}

Krok 3 - usporiadajte naše údaje do kategórií

Implementujme nasledujúci kód do metódy vykreslenia, aby sme úlohy zoskupili do ich príslušných kategórií wipa complete. Pokojne pridajte ďalšie kategórie a hrajte s kódom.

Vyššie uvedený kód môžete skopírovať a vložiť z nasledujúceho úryvku.

render() { var tasks = { wip: [], complete: [] } this.state.tasks.forEach ((t) => { tasks[t.category].push( this.onDragStart(e, t.name)} draggable className="draggable" style={{backgroundColor: t.bgcolor}}> {t.name} ); });

Vo vyššie uvedenom kóde prechádzame všetky úlohy a vytvárame div pre každú položku úlohy a ukladáme ju do príslušných kategórií.

Takže wip[]obsahuje všetky úlohy v kategórii WIP a complete[]obsahuje všetky splnené úlohy.

Krok 4 - vykonajte presunutie položky úlohy

Ak chcete, aby sa dal prvok presúvať, pridajte do každého prvku ľubovoľný prvok. Textový formát kódu nájdete v bloku kódu vyššie.

Krok 5 - vytvorte kvapkovaciu nádobu

Ak chcete vytvoriť droppable kontajner, implementujte dragover event. Teraz, keď chceme zakázať predvolenú udalosť presunutia, jednoducho zavoláme event.preventDefault()udalosť z udalosti presunutia.

Vykreslíme tiež {tasks.wip}a {tasks.complete}v ich zodpovedajúcich prvkoch div.

return ( 

DRAG & DROP DEMO

this.onDragOver(e)} onDrop={(e)=>{this.onDrop(e, "wip")}}> WIP {tasks.wip} this.onDragOver(e)} onDrop={(e)=>this.onDrop(e, "complete")}> COMPLETED {tasks.complete} );
Let us now implement the onDragOver() event handler.

Doterajší výstup bude vyzerať ako na nasledujúcom obrázku.

Krok 6 - zachytenie stavu prvku, ktorý sa ťahá

Let’s modify the code where we are creating the category for each task. Add an eventhandler ondragstart and pass the id/name or any information you need to persist while the drag/drop is happening.

I am using name as a unique value to identify the task. Feel free to use ID or whatever unique key you have.

Let’s now implement the onDragStart event handler.

In the onDragStart handler, we grab the parameter and store that within the dataTransfer object. (Don’t get confused by the parameter naming, as I guess I was in a different naming world while coding this :) .)

IE note: this may not work with IE. For IE, the better practice is to give the format as the key as shown below.

Instead of
ev.dataTransfer.setData("id", id)
USE
ev.dataTransfer.setData(“text/plain”,id)

The above handler will ensure that the element being dragged is stored in the event object and is available for use when required. It may be required while dropping on a target.

Now if you run the application and drag the elements, the following logs will be output.

Step 7 — handle the drop event.

Let’s open up the render method and add the onDrop event to the div with a className of droppable.

In the above code, we add the drop event handler, and pass the required category complete as an argument. This indicates we are dropping the element from the wip state to the complete state (category). Please feel free to change the names, as required.

Let’s now implement the onDrop() event handler.

Here’s the code you can copy/paste:

onDrop = (ev, cat) => { let id = ev.dataTransfer.getData("id"); let tasks = this.state.tasks.filter((task) => { if (task.name == id) { task.category = cat; } return task; }); this.setState({ ...this.state, tasks }); }

In the onDrop event handler, we grab the task being dragged by using getData method on the event’s dataTransfer object.

We then create a new tasks array by using the filter method, and change the category of the task being dragged.

setState() will trigger render, and the tasks will be rendered in the right areas.

IE note: To make it work in IE, use the below getData method.

Instead of

var id = ev.dataTransfer.getData(“id”)

use

var id = ev.dataTransfer.getData(“text”)

Step 8 — to implement drop from “complete” to “wip,” add the onDrop handler

The onDrop() handler remains the same as earlier.

Finally, run the code and marvel at your creation :) and have fun while coding.

You can grab the source code from here.

Note: for this to work cross browser, change the setData type to string.

napríklad na nastavenie dát použite ev.dataTransfer.setData(“text/plain”,id). Ak chcete čítať údaje, použitevar id = ev.dataTransfer.getData(“text”)

Pretože mojím cieľom bolo demonštrovať základné funkcie drag and drop, kód nebol optimalizovaný pre faktory, ako sú napríklad konvencie návrhu a pomenovania.

Learn with me @Learner + Fullstack Coach (@rajeshpillai): //twitter.com/rajeshpillai

Propagácia: Špeciálny kupón v hodnote 10 $ pre stredných čitateľov na môj nadchádzajúci živý kurz ReactJS-Beyond the basics na Udemy v prípade, že chcete podporiť naše otvorené učebné osnovy Mastering frontend engineering za 12 až 20 týždňov.

Práve som zverejnil môj kurz prednostného prístupu Javascript Deep Dive - Kódujte si svoj vlastný Reagovať