2012-02-09 14 views
7

Estoy tratando de lograr el mismo efecto que en imgur.com (arrastre un archivo desde el escritorio a imgur.com y verá una imagen genial cubrir). ya tiene una solución de trabajo gracias a esta publicación: Event propagation, overlay and drag-and-drop eventsMostrar superposición en 'dragenter' al arrastrar un archivo desde el escritorio al navegador

PERO: me parece la solución bastante insatisfactoria. el problema es $ (document) .on ('dragenter') se dispara varias veces al pasar el ratón sobre elementos secundarios. Estaba buscando un evento que se dispara UNA VEZ cuando entro en la ventana gráfica y UNA VEZ que salgo de la ventana gráfica para poder tener $ overlay.fadeIn() y .fadeOut() limpios en dragenter y dragleave.

Lo resolví con un elemento transparente que llena toda la ventana gráfica. Luego llamo a dragenter sobre ese elemento transparente en lugar de sobre $ (documento). con $ ('*: visible'). live ('dragenter') luego muestro la superposición oculta y real. $ ('# transparentOverlay'). on ('dragleave') oculta las superposiciones. bastante hacky pero funciona (al menos en Safari/Chrome/Firefox)

pero sólo el selector de $ ('*: Visible'). live() me da un dolor de cabeza ...

Alguien tiene una mejor ¿sugerencia?

Respuesta

2

Puede que necesite ver más código/errores que está experimentando. ¿Has probado un booleano simple para verificar cuándo se ha disparado tu evento y limitar los eventos posteriores?

var dragging = false; 

$(document).on('dragenter', function(){ 
    if(!dragging){ 
     //DO SOMETHING 
     dragging = true; 
    } 
}); 

$(document).on('dragleave', function(){ 
    if(dragging){ 
     //DO SOMETHING 
     dragging = false; 
    } 
}); 
9

Pruébalo así, lo que funciona bien para mí. Esencialmente, es imitando a los dragenter y dragleave eventos, pero sólo usando dragover:

;(function() { 
    var isOver = false, interval; 

    $(document).on('dragover', function(e) { 
     e.preventDefault(); 

     clearInterval(interval); 

     interval = setInterval(function() { 
      isOver = false; 
      clearInterval(interval); 

      /*** callback for onDragLeave ***/ 
     }, 100); 

     if (!isOver) { 
      isOver = true; 

      /*** callback for onDragEnter ***/ 
     } 
    }); 
})(); 
+0

Esta es la única solución que he encontrado que funcionó a la perfección .. . No estoy seguro de si habrá problemas con el intervalo setinterval y la pérdida de memoria, pero hasta ahora, funcionó perfectamente. –

+0

¿Alguien ha encontrado una solución mejor desde esta vez? – BastienSander

+0

¿Por qué escribió su respuesta en francés en primer lugar? ¿Y luego traducirlo al inglés? – ozanmuyes

1

Una versión más ligera de la respuesta anterior:

;(function() { 
    var dragTimeout; 

    $(document).on('dragenter', function(e) { 
     // dragenter code 
    }); 

    $(document).on('dragleave', function(e) { 
     dragTimeout = setTimeout(function() { 
      dragTimeout = undefined; 
      // your dragleave code 
     }); 
    }); 

    $(document).on('dragover', function(e) { 
     if (dragTimeout) { 
      clearTimeout(dragTimeout); 
      dragTimeout = undefined; 
     } 
    }); 
})(); 
Cuestiones relacionadas