2017-07-07 1 views
1

Je voudrais être en mesure de détecter quand un utilisateur fait glisser un fichier dans la fenêtre et afficher une superposition sur l'ensemble de l'application qui montre les différents dossiers que l'utilisateur pourrait télécharger le fichier. Jusqu'à présent, je comprends que je peux écouter la fenêtre pour "dragenter" et montrer ma superposition, et écouter la superposition de "dragleave" pour le cacher, mais le problème semble être que glisser sur les zones de dépôt provoque le déclenchement de l'événement dragleave de la superposition, ce qui rend la superposition masquée (ce qui fait que l'événement dragenter de la fenêtre affiche la superposition, et ainsi de suite). J'utilise Dropzone.js pour mon dossier dropzones. J'ai regardé autour de moi et j'ai vu des problèmes similaires aux miens, mais aucun qui résout ce problème.Comment gérer le glisser-déposer de fichiers avec une superposition de fenêtre et plusieurs zones de dépôt?

Modifier: J'ai trouvé une solution (de toutes sortes) ailleurs sur StackOverflow: jQuery Drag-and-Drop Flickering on Hover (Webkit only)

La solution est de vérifier l'événement sur DragLeave et, si le pageX et pageY sont tous deux 0, cela signifie que le DragLeave était parce que l'utilisateur a quitté la fenêtre, plutôt que traîné sur l'une des zones de dépôt.

+0

Pour quel but vous voulez montrer la superposition? Pour arrêter le téléchargement de fichier? –

+0

La page affichera par défaut les fichiers déjà téléchargés. Lorsque l'utilisateur fait glisser un fichier sur l'écran, la superposition affiche les dossiers disponibles sur lesquels il peut télécharger (un peu comme comment imgur.com traite les superpositions de téléchargement de fichiers, sauf avec plusieurs zones de largage et aucune zone de largage globale). Ainsi, l'objectif de la superposition est d'afficher les zones de dépôt de dossier à l'utilisateur. –

+0

Vous souhaitez simplement afficher la superposition ou attendre une saisie de l'utilisateur, par exemple en sélectionnant le dossier de la superposition? –

Répondre

0

Dans ce scénario spécifique (utilisation d'instances Dropzone dans une superposition en plein écran uniquement visible lorsque vous faites glisser un fichier et où vous souhaitez uniquement que les utilisateurs placent des fichiers sur les zones de dépôt), voici ce que j'ai fait pour résoudre le problème. problème.

  • Écouter la fenêtre pour « dragenter »
    • si l'événement objet dataTransfer a un tableau de types avec 1 élément présent et types [0] == « Fichiers » montrent alors la superposition (cette façon, nous ne montrent pas la superposition si quelque chose comme du texte est en cours de déplacement)
  • Écoutez votre musique sur la superposition pour « DragLeave »
    • si l'événement DragLeave pageX et pageY sont tous deux 0, l'utilisateur d haillons sur le document et nous devons cacher la superposition, sinon ils traînent sur l'un des dropzones
  • Écoutez votre musique sur la superposition pour « dragover »
    • s'il y a des éléments sur l'écran avec un classe de "dz-drag-hover" puis définissez l'événement dataTransfer.dropEffect sur "copy" car nous survolons une zone de dépôt
    • sinon, définissez l'événement dataTransfer.DropEffect "none" et preventDefault()

Voici quelques javascript non testé ci-dessus:

function handleDragEnter(e) { 
    // make sure we're dragging a file 
    var dt = (e && e.dataTransfer); 
    var isFile = (dt && dt.types && dt.types.length == 1 && dt.types[0] == "Files"); 
    if (isFile) { 
     // and, if so, show the overlay 
     showOverlay(); 
    } 
} 

function handleDragLeave(e) { 
    // was our dragleave off the page? 
    if (e && e.pageX == 0 && e.pageY == 0) { 
     // then hide the overlay 
     hideOverlay(); 
    } 
} 

function handleDragOver(e) { 
    // look for any dropzones being hovered 
    var isHovering = document.getElementsByClassName("dz-drag-hover").length > 0; 
    if (isHovering) { 
     // found some? then we're over a dropzone and want to allow dropping 
     e.dataTransfer.dropEffect = 'copy'; 
    } else { 
     // we're just on the overlay. don't allow dropping. 
     e.dataTransfer.dropEffect = 'none'; 
     e.preventDefault(); 
    } 
} 

function showOverlay() { 
    // only show the overlay if it's not already shown (can prevent flickering) 
    if (getComputedStyle(overlay, null).display == "none") 
     overlay.style.display = "block"; 
    } 
} 

function hideOverlay() { 
    overlay.style.display = "none"; 
} 

// listen to dragenter on the window for obvious reasons 
window.addEventListener("dragenter", handleDragEnter); 
// our fullscreen overlay will cover up the window, so we need to listen to it for dragleave events 
overlay.addEventListener("dragleave", handleDragLeave); 
// same thing for dragover 
overlay.addEventListener("dragover", handleDragOver); 
0

L'événement dragleave se déclenche très rapidement que nous le pensions afin que nous puissions retarder le processus.

Dropzone.autoDiscover = false; 
$("div#upload").dropzone({ 
    url: "upload.php", 
    addRemoveLinks:true, 
    paramName:"composeUpload", 
    init: function() { 
     myDropZone = this; 
     this.on('dragover', function(e,xhr,formData){ 
      $('.overlay').fadeIn(); 
      stopLoading(); //stops local file opens 
      return false; 
     }); 
     this.on('dragleave', function(e,xhr,formData){ 
      setTimeout(function(){ 
      $('.overlay').fadeIn(); 
      },8000); 
     });   
    } 
}); 

si vous déposez des fichiers sur vide div ou une superposition du navigateur ouvre le fichier localement donc nous devons arrêter la valeur par défaut

function stopLoading(){ 
    window.addEventListener("dragover",function(e){ 
    e = e || event; 
    e.preventDefault(); 
    },false); 
    window.addEventListener("drop",function(e){ 
    e = e || event; 
    e.preventDefault(); 
    },false); 
} 

Je ne pas que ce soit la réponse que vous cherchez, mais il va certainement vous donner une idée.Merci.