2012-09-20 17 views
5

Tengo un pequeño problema con html5 arrastrar y soltar. No veo una manera fácil de salir de eso. Básicamente tengo algunas "cajas" con algunos otros elementos html dentro. Los cuadros principales son arrastrables y pueden soltarse entre sí.html5: hay una manera de evitar que los niños interfieran con los eventos de arrastre

Adjunto dragover evento en el cuerpo para manejar arrastrar y soltar en toda la página. El problema es que cuando arrastras las casillas, el evento a veces se desencadena en elementos secundarios y el padre no obtiene este evento.

¿Hay alguna manera fácil de evitar que esto suceda?

Básicamente quiero que el evento de dragover se dispare tan pronto como el mouse esté en el área del cuadro de destino. Conozco un par de formas de resolver esto, pero son realmente feas y me preguntaba si tal vez haya algo simple.

Gracias por sus pensamientos

Versión corta de lo que estoy haciendo en código:

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

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


}, false); 

Pero en mi caso, los elementos secundarios están tomando casi todo el cuadro '.candrophere' por lo que el evento casi nunca se disparó en el destino correcto (sobre todo cuando muevo el ratón más rápido)

+1

Debe publicar el código que está fallando para que las personas puedan ayudarlo. – Nelson

+0

Actualizado con algún pseudo código sin distracciones – Marius

+0

Pude arreglar esto simplemente usando el evento dragover en lugar del evento dragenter –

Respuesta

1

Básicamente mi solución es la siguiente:

Desde correo .target y e.currentTarget no pueden coincidir con el cuadro primario la mayor parte del tiempo; todo lo que queda por hacer es verificar manualmente si e.target es un elemento secundario del cuadro principal. Hay muchas formas de hacerlo, pero estoy usando una función personalizada. No se puede publicar aquí, ya que se basa en mi propio marco y no funcionará sin él de todos modos, pero el pseudo-código es el siguiente:

// 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

El css pointer-events regla evita eventos de interacción del ratón de cocción en los elementos a los que se aplica, pero que actualmente no es compatible con IE (http://caniuse.com/pointer-events).

Una solución que he usado para este problema es añadir algo así como

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

a su CSS, y añadir la clase is-drag-in-progress al elemento body en el controlador onDragStart (y quitarlo cuando los extremos de arrastre) Esto evitará que los elementos secundarios interfieran con los eventos de arrastre en el elemento primario.

+0

Guau, esto funciona muy bien. En Chrome al menos. – mwilcox

Cuestiones relacionadas