Tutorial pentru HTML5 drag&drop – lista sortabilă (Programare, Javascript, Html)

tobbe a intrebat.

Știe cineva un tutorial foarte bun pentru HTML5 drag&drop? Fac o listă toDo-list și vreau să pot reordona / sorta cu acest API. Am căutat pe Google ca un nebun și acum am început să renunț… Orice sfat este binevenit!Mulțumesc!

p.s Chiar vreau să folosesc html5 drag&drop API, nu jQuery-sortable()

Comentarii

  • De ce nu cauți asta? Primul rezultat din Google acoperă tot ce ai nevoie… –  > Por Mike Robinson.
  • Am. Dar pur și simplu nu pot găsi unul bun care să explice elementele de bază într-un mod BUN. (da, sunt destul de nou în javascript) –  > Por tobbe.
  • Este încă surprinzător de dificil să găsești aceste informații. Suntem în 2018, încă mai folosim jQuery-sortable peste tot? Există o mulțime de tutoriale HTML5 drag and drop, dar nimic care să acopere reordonarea. –  > Por SistemParadox.
  • Îmi dau seama că acesta este un fir incredibil de vechi, dar vă rugăm să rețineți că comentarii precum „De ce nu căutați pur și simplu? Primul rezultat în Google acoperă tot ce ai nevoie” nu numai că nu sunt utile, dar, în mod ironic, acesta este acum primul rezultat pe Google. Acest lucru ar trebui să sugereze că informația nu a fost atât de răspândită pe cât credea comentatorul. –  > Por logic8.
4 răspunsuri
davidf

Am încercat să păstrez acest eșantion cât mai simplu posibil.

Dacă creați o listă HTML:

<ul>
  <li draggable="true" ondragover="dragOver(event)" ondragstart="dragStart(event)">Apples</li>
  <li draggable="true" ondragover="dragOver(event)" ondragstart="dragStart(event)">Oranges</li>
  <li draggable="true" ondragover="dragOver(event)" ondragstart="dragStart(event)">Bananas</li>
  <li draggable="true" ondragover="dragOver(event)" ondragstart="dragStart(event)">Strawberries</li>
</ul>

…și următorul javascript:

var _el;

function dragOver(e) {
  if (isBefore(_el, e.target))
    e.target.parentNode.insertBefore(_el, e.target);
  else
    e.target.parentNode.insertBefore(_el, e.target.nextSibling);
}

function dragStart(e) {
  e.dataTransfer.effectAllowed = "move";
  e.dataTransfer.setData("text/plain", null); // Thanks to bqlou for their comment.
  _el = e.target;
}

function isBefore(el1, el2) {
  if (el2.parentNode === el1.parentNode)
    for (var cur = el1.previousSibling; cur && cur.nodeType !== 9; cur = cur.previousSibling)
      if (cur === el2)
        return true;
  return false;
}

… ar trebui să obțineți o listă sortabilă.

Puteți încerca codul pe https://codepen.io/crouchingtigerhiddenadam/pen/qKXgap

Vă rugăm să fiți atenți la următorul bug din FireFox:https://developer.mozilla.org/en-US/docs/Web/Events/dragenter

Sper că vă ajută.

Comentarii

  • Adăugarea e.dataTransfer.setData('text/plain',null) la evenimentul dragstart a făcut să funcționeze pe Firefox –  > Por bqlou.
  • Mă uit exact ca aceasta, dar acest lucru nu funcționează în mobil și Ipad. cum putem face acest lucru pentru dispozitiv mobil, de asemenea????? –  > Por Crock.
  • Ați putea folosi „touchstart”. În ceea ce privește browserul, evenimentele de atingere și evenimentele de mouse ar trebui să fie separate. Dacă aveți un laptop hibrid, veți avea atât un mouse, cât și o intrare tactilă. Cu toate acestea, am constatat că pe unele browsere desktop se întâmplă lucruri ciudate atunci când folosiți evenimentul touchmove. De exemplu, obiectul poate zbura de pe ecran atunci când faceți clic pe el cu mouse-ul. Într-o zi sunt sigur că specificațiile se vor stabili și totul va funcționa corect. Doar că nu suntem încă acolo. –  > Por davidf.
  • Care este scopul funcției isBefore()? Este iterația prin toți frații anteriori pentru a vedea dacă elementul trasat curent se află în el? Vă rugăm să explicați… –  > Por R OMS.
  • cur.nodeType !== 9 poate fi în schimb cur.nodeType !== Node.DOCUMENT_NODE pentru a fi mai ușor de citit… –  > Por reikyoushin.
KendallB

Pentru un tutorial de la început până la sfârșit, verifică asta: http://taximeeting.tumblr.com/post/26539340142/lightweight-jquery-plugin-for-html5-sortable-lists.

Se bazează pe html5sortable: http://farhadi.ir/projects/html5sortable/. Un alt tutorial foarte bun despre funcția de glisare și fixare din HTML5 poate fi găsit aici: http://www.html5rocks.com/en/tutorials/dnd/basics/.

Comentarii

  • Autorul nu este dispus să se ocupe de dependențele jQuery. – „not jQuery-sortable()” –  > Por Dzintars.
cmpenney

Dacă doriți să faceți acest lucru cu rânduri de tabel, trebuie să faceți o mică modificare:

https://jsfiddle.net/cmpenney/6rx6u2kf/

<table>
    <tr draggable="true" ondragenter="dragenter(event)" ondragstart="dragstart(event)">
        <td style="border: 1px solid black">Apples</td>
        <td style="border: 1px solid black">A-Column2</td>
    </tr>
    <tr draggable="true" ondragenter="dragenter(event)" ondragstart="dragstart(event)">
        <td style="border: 1px solid black">Oranges</td>
        <td style="border: 1px solid black">O-Column2</td>
    </tr>
    <tr draggable="true" ondragenter="dragenter(event)" ondragstart="dragstart(event)">
        <td style="border: 1px solid black">Bananas</td>
        <td style="border: 1px solid black">B-Column2</td>
    </tr>
    <tr draggable="true" ondragenter="dragenter(event)" ondragstart="dragstart(event)">
        <td style="border: 1px solid black">Strawberries</td>
        <td style="border: 1px solid black">S-Column2</td>
    </tr>
</table>



var source;

function isbefore(a, b) {
    if (a.parentNode == b.parentNode) {
        for (var cur = a; cur; cur = cur.previousSibling) {
            if (cur === b) {
                return true;
            }
        }
    }
    return false;
}

function dragenter(e) {
    var targetelem = e.target;
    if (targetelem.nodeName == "TD") {
       targetelem = targetelem.parentNode;   
    }  

    if (isbefore(source, targetelem)) {
        targetelem.parentNode.insertBefore(source, targetelem);
    } else {
        targetelem.parentNode.insertBefore(source, targetelem.nextSibling);
    }
}

function dragstart(e) {
    source = e.target;
    e.dataTransfer.effectAllowed = 'move';
}

Bene Laci

Dacă optați pentru soluția de adamf (Mar 10 ’15 la 11:16), și doriți să o utilizați pe rânduri de tabel, înlocuiți dragenter cu următoarea funcție:

function dragenter(e) {
    var target = e.target;
    while (target.parentNode.tagName != 'TBODY') {
        target = target.parentNode;
    }

    if (isbefore(source, target)) {
        target.parentNode.insertBefore(source, target);
    }
    else {
        target.parentNode.insertBefore(source, target.nextSibling);
    }
}

În acest fel, ținta se va aplica numai pentru elementele TR, și nu pentru oricare dintre elementele lor copil.

Același lucru s-ar aplica și pentru ul > li în cazul în care se va aplica li au copii.

În cazul în care există img elemente copil, se adaugă un element draggable=”false” la fiecare dintre ele.