2012-09-20 9 views
5

Ho un po 'di problema con html5 trascinamento. Non vedo un modo semplice per uscirne. Fondamentalmente ho alcune "scatole" con alcuni altri elementi HTML all'interno. Le caselle genitore sono trascinabili e possono essere rilasciate l'una sull'altra.html5: c'è un modo per impedire ai bambini di interferire con gli eventi di trascinamento

È possibile associare l'evento dragover sul corpo per gestire il trascinamento dell'intera pagina. Il problema è che quando si trascinano le caselle, a volte l'evento viene attivato sugli elementi figlio e il genitore non riceve affatto questo evento.

C'è un modo semplice per evitare che ciò accada?

Fondamentalmente voglio che l'evento di trascinamento si attivi appena il mouse si trova nell'area della casella di destinazione. Conosco un paio di modi per risolvere questo problema, ma sono davvero brutti e mi chiedevo se forse c'è qualcosa di semplice.

Grazie per i vostri pensieri

Versione corta di quello che sto facendo in codice:

document.addEventListener('dragenter', function(e) { 

    if (e.target.className == 'candrophere') 
     // cancel out "e" to allow drop 


}, false); 

Ma nel mio caso gli elementi figlio stanno prendendo quasi l'intera scatola '.candrophere' in modo che il evento viene quasi mai sparato sul bersaglio corretto (soprattutto quando muovo il mouse più veloce)

+1

Dovresti pubblicare il codice che non funziona, in modo che le persone possano aiutarti. – Nelson

+0

Aggiornato con qualche pseudo-codice senza alcuna distrazione – Marius

+0

Sono stato in grado di risolvere questo problema semplicemente utilizzando l'evento di trascinamento invece dell'evento dragenter –

risposta

1

Fondamentalmente la mia soluzione è la seguente:

Dato e .target e e.currentTarget non possono essere abbinati alla casella genitore il più delle volte - tutto ciò che resta da fare è controllare manualmente se e.target è figlio della casella genitore. Ci sono molti modi per farlo, ma sto usando una funzione personalizzata. Non può postare qui, in quanto si basa sul mio quadro e non funzionerà senza comunque, ma la pseudo-codice è il seguente:

// target is a framework object (much like jquery) 
closestDroppableParent = function(target) 
{ 
    // i know that all children in those boxes will not be any deeper than this 
    var max_levels = 5; 

    while (target && max_levels > 0) 
    { 
     max_levels--; 

     // droppable boxes have data-droptype attribute set so only other boxes with the same attribute 
     // can be dropped on them. This check can be done any way you like. You can have a custom class 
     // for droppable objects, check for draggable attribute etc... 
     // .data() is a framework function that returns the value of the data-* attributes 
     if (target.data('droptype')) 
      return target; 

     // .parent() is a framework function to get parent node 
     target = target.parent(); 
    } 

    return null; 
} 


// drag over event 
dragOverEventHandler = function(e) 
{ 
    // convert the element to its closest droppable parent 
      // $() is much like jquery 
    var closest = closestDroppableParent($(e.target)); 

    if (closest) 
     closest.addClass('draggedOver'); 
} 
13

il CSS pointer-events regola impedisce eventi di interazione del mouse da sparo sugli elementi a cui è applicato, ma attualmente non è supportato da IE (http://caniuse.com/pointer-events).

Una soluzione che ho usato per questo problema è quello di aggiungere qualcosa di simile

.is-drag-in-progress .child-elements 
{ 
    pointer-events:none; 
} 

al vostro CSS, e aggiungere la classe is-drag-in-progress all'elemento body nel onDragStart gestore (e rimuoverlo quando finisce il trascinamento). Ciò impedirà agli elementi secondari di interferire con gli eventi di trascinamento sull'elemento padre.

+0

Wow, funziona perfettamente. Almeno in Chrome. – mwilcox

Problemi correlati