元素。问题当我将文件拖到
上时,会按预期触发 dragenter 事件。但是,当我将鼠标移到子元素(例如
)上时,会为
元素触......" /> 元素。问题当我将文件拖到
上时,会按预期触发 dragenter 事件。但是,当我将鼠标移到子元素(例如
)上时,会为
元素触......"> 元素。问题当我将文件拖到
上时,会按预期触发 dragenter 事件。但是,当我将鼠标移到子元素(例如
)上时,会为
元素触......" />
ChatGPT解决这个技术问题 Extra ChatGPT

'dragleave' of parent element fires when dragging over children elements

Overview

I have the following HTML structure and I've attached the dragenter and dragleave events to the <div id="dropzone"> element.

<div id="dropzone">
    <div id="dropzone-content">
        <div id="drag-n-drop">
            <div class="text">this is some text</div>
            <div class="text">this is a container with text and images</div>
        </div>
    </div>
</div>

Problem

When I drag a file over the <div id="dropzone">, the dragenter event is fired as expected. However, when I move my mouse over a child element, such as <div id="drag-n-drop">, the dragenter event is fired for the <div id="drag-n-drop"> element and then the dragleave event is fired for the <div id="dropzone"> element.

If I hover over the <div id="dropzone"> element again, the dragenter event is again fired, which is cool, but then the dragleave event is fired for the child element just left, so the removeClass instruction is executed, which is not cool.

This behavior is problematic for 2 reasons:

I'm only attaching dragenter & dragleave to the

so I don't understand why the children elements have these events attached as well. I'm still dragging over the
element while hovering over its children so I don't want dragleave to fire!

jsFiddle

Here's a jsFiddle to tinker with: http://jsfiddle.net/yYF3S/2/

Question

So... how can I make it such that when I'm dragging a file over the <div id="dropzone"> element, dragleave doesn't fire even if I'm dragging over any children elements... it should only fire when I leave the <div id="dropzone"> element... hovering/dragging around anywhere within the boundaries of the element should not trigger the dragleave event.

I need this to be cross-browser compatible, at least in the browsers that support HTML5 drag-n-drop, so this answer is not adequate.

It seems like Google and Dropbox have figured this out, but their source code is minified/complex so I haven't been able to figure this out from their implementation.

Prevent event propagation via e.stopPropagation();
I think I already am... check out the update
Can you post a demo somewhere on jsfiddle.net people can tinker with it?
@Blender... sure thing, give me a couple of minutes!
@Blender... I updated my question with a fiddle

B
Ben Rudolph

If you don't need to bind events to the child elements, you can always use the pointer-events property.

.child-elements {
  pointer-events: none;
}

Best solution! I didn't even think that I could solve the problem using css in such an elegant way. Thank you very much!
The only downside to this approach is that it nukes all pointer events on child elements (eg they can no longer have separate :hover styles or click event handlers). In case you want to preserve those events, here's another workaround I've been using: bensmithett.github.io/dragster
Combine with css child selector to reach all children of your dropzone: .dropzone * {pointer-events: none;}
You're already using jQuery, so just $('.element').addClass('dragging-over') to the element you're dragging over, and $('.element').removeClass('dragging-over') when you drag out. Then in your CSS you can have .element.dragging-over * { pointer-events: none; }. That removes pointer events from all child elements only when you're dragging over.
This solution worked amazingly well when using jQuery and jQuery UI in a large grid system with hundreds of elements. My issue was that the text inside the container would be selectable and users would attempt to drag and drop a span instead of the drag/drop li item. This simple CSS removed the ability and works great.
C
Community

I finally found a solution I'm happy with. I actually found several ways to do what I want but none were as successful as the current solution... in one solution, I experienced frequent flickering as a result of adding/removing a border to the #dropzone element... in another, the border was never removed if you hover away from the browser.

Anyway, my best hacky solution is this:

var dragging = 0;

attachEvent(window, 'dragenter', function(event) {

    dragging++;
    $(dropzone).addClass('drag-n-drop-hover');

    event.stopPropagation();
    event.preventDefault();
    return false;
});

attachEvent(window, 'dragover', function(event) {

    $(dropzone).addClass('drag-n-drop-hover');

    event.stopPropagation();
    event.preventDefault();
    return false;
});

attachEvent(window, 'dragleave', function(event) {

    dragging--;
    if (dragging === 0) {
        $(dropzone).removeClass('drag-n-drop-hover');
    }

    event.stopPropagation();
    event.preventDefault();
    return false;
});

This works pretty well but issues came up in Firefox because Firefox was double-invoking dragenter so my counter was off. But nevertheless, its not a very elegant solution.

Then I stumbled upon this question: How to detect the dragleave event in Firefox when dragging outside the window

So I took the answer and applied it to my situation:

$.fn.dndhover = function(options) {

    return this.each(function() {

        var self = $(this);
        var collection = $();

        self.on('dragenter', function(event) {
            if (collection.size() === 0) {
                self.trigger('dndHoverStart');
            }
            collection = collection.add(event.target);
        });

        self.on('dragleave', function(event) {
            /*
             * Firefox 3.6 fires the dragleave event on the previous element
             * before firing dragenter on the next one so we introduce a delay
             */
            setTimeout(function() {
                collection = collection.not(event.target);
                if (collection.size() === 0) {
                    self.trigger('dndHoverEnd');
                }
            }, 1);
        });
    });
};

$('#dropzone').dndhover().on({
    'dndHoverStart': function(event) {

        $('#dropzone').addClass('drag-n-drop-hover');

        event.stopPropagation();
        event.preventDefault();
        return false;
    },
    'dndHoverEnd': function(event) {

        $('#dropzone').removeClass('drag-n-drop-hover');

        event.stopPropagation();
        event.preventDefault();
        return false;
    }
});

This is clean and elegant and seems to be working in every browser I've tested so far (haven't tested IE yet).


This is the best solution so far.The only problem is this code doesn't work when you add a file, remove it and drag another file over it. Only after raising HoverEnd and raising HoverStart again this code works again.
@MysticEarth can you put together a jsFiddle to demo when it doesn't work?
Thank you for your answer. This was really helpful, as the HTML5 drag and drop interface and event listeners can be really painfull. This is the best way to handle the crazy events, especially when you want to handle multiple instances of drop zone elements.
Why do we need to call stopPropagation() preventDefault() and return false. Return false should be enough. Should It ?
It is redundant, but calling stopPropagation() and preventDefault() is preferred. I'd drop the return false.
h
hacklikecrack

This is a little ugly but it works dammit!...

On your 'dragenter' handler store the event.target (in a variable inside your closure, or whatever), then in your 'dragleave' handler only fire your code if event.target === the one you stored.

If your 'dragenter' is firing when you don't want it to (i.e. when it's entering after leaving child elements), then the last time it fires before the mouse leaves the parent, it's on the parent, so the parent will always be the final 'dragenter' before the intended 'dragleave'.

(function () {

    var droppable = $('#droppable'),
        lastenter;

    droppable.on("dragenter", function (event) {
        lastenter = event.target;
        droppable.addClass("drag-over");            
    });

    droppable.on("dragleave", function (event) {
        if (lastenter === event.target) {
            droppable.removeClass("drag-over");
        }
    });

}());

I'll give this a try later. If anything, it looks cleaner than my solution but I can't be sure how cross-browser compatible it is just by looking at it. Where have you tested this?
only Chrome, and may only work on an assumption that there is a physical gap between the child elements and the container.
My favourite answer on here. Doesn't feel ugly at all :)
Works for me in IE, Chrome, FF
This does not work if the drag start on the children. For example, dragging from something from another window in a way that drag starts inside the child.
b
bargar

At first, I agreed with folks discarding the pointer-events: none approach. But then I asked myself:

Do you really need pointer-events to work on the child elements while dragging is in progress?

In my case, I have lots of stuff going on in the children, e.g. hover to show buttons for additional actions, inline-editing, etc... However, none of that is necessary or in fact even desired during a drag.

In my case, I use something like this to turn pointer events off selectively for all child nodes of the parent container:

  div.drag-target-parent-container.dragging-in-progress * {
    pointer-events: none;
  }

Use your favorite approach to add/remove the class dragging-in-progress in the dragEnter/dragLeave event handlers, as I did or do the same in dragStart, et. al.


This solution is both the simplest and is (as far as I can tell) full-proof. Simply add the class in the dragstart event and remove it in dragend.
This is pretty nice solution but not perfect. If the drag starts on the child element (dragging from another window), dragEnter is never fired. It's probably also possible to move mouse fast enough that the dragEnter is not fired when you move to the child, but not 100% sure about that.
I confirm @FINDarkside comment on being able to drag fast enough to skip a few events, and mess up the process.
B
Blender

This seems to be a Chrome bug.

The only workaround that I could think of was to create a transparent overlay element to capture your events: http://jsfiddle.net/yYF3S/10/

JS:

$(document).ready(function() {
    var dropzone = $('#overlay');

    dropzone.on('dragenter', function(event) {
        $('#dropzone-highlight').addClass('dnd-hover');
    });

    dropzone.on('dragleave', function(event) {
        $('#dropzone-highlight').removeClass('dnd-hover');
    });

});​

HTML:

<div id="dropzone-highlight">
    <div id="overlay"></div>

    <div id="dropzone" class="zone">
        <div id="drag-n-drop">
            <div class="text1">this is some text</div>
            <div class="text2">this is a container with text and images</div>
        </div>
    </div>
</div>

<h2 draggable="true">Drag me</h2>
​

thanks for the answer, Blender. I've already tried this however. The problem with this solution is that the overlay element "overlays" the children elements, which I need to interact with... so having an overlay disables the interaction I need with the children... think of it as a file drag-n-drop box... you can drag and drop or you can click the input element to select your files.
here's an example fiddle that your solution does not satisfy... jsfiddle.net/UnsungHero97/yYF3S/11
I'm confused. Why do you need to interact with the child elements as well?
In my particular case, a child element of the "dropzone" is a file select button... so if I don't want to drag and drop files, I can select them using the input element. But with the overlay... I can't click the input element. make sense?
@Blender Most cases we need to drag a file from desktop, not an element from page, so this kinda not works.
O
Oliver

The problem is, that your elements inside the dropzones are of course part of the dropzone and when you enter the children, you leave the parent. Solving this is not easy. You might try adding events to the children too adding your class again to the parent.

$("#dropzone,#dropzone *").on('dragenter', function(event) {

    // add a class to #dropzone

    event.stopPropagation(); // might not be necessary
    event.preventDefault();
    return false;
});

Your events will still fire multiple times but nobody will see.

//Edit: Use the dragmove event to permanently overwrite the dragleave event:

$("#dropzone,#dropzone *").on('dragenter dragover', function(event) {

    // add a class to #dropzone

    event.stopPropagation(); // might not be necessary
    event.preventDefault();
    return false;
});

Define the dragleave event only for the dropzone.


that won't solve the problem though. The real issue is dragleave... when I leave a child, I might still be within the parent #dropzone but that won't fire the dragenter event again :(
Are you sure, that the dragenter is not fired again?
Ah right... it is fired again, however, after it is fired, the dragleave event is fired for the child element just left, so again the removeClass instruction is executed
I can't define dragleave only for the #dropzone... if I could, I wouldn't have this problem.
No, I meant don't add events for dragleave to the children.
C
Community

As benr mentioned in this answer, you can prevent child nodes to fire on events, but if you need to bind some events, do this:

#dropzone.dragover *{
   pointer-events: none;
}

And add this one to your JS code:

$("#dropzone").on("dragover", function (event) {
   $("#dropzone").addClass("dragover");
});

$("#dropzone").on("dragleave", function (event) {
   $("#dropzone").removeClass("dragover");
});

For me this results in the overlay flashing constantly.
n
nkkollaw

If you're using jQuery, check this out: https://github.com/dancork/jquery.event.dragout

It's truly awesome.

Special event created to handle true dragleave functionality. HTML5 dragleave event works more like mouseout. This plugin was created to replicate the mouseleave style functionality whilst dragging. Usage Example: $('#myelement').on('dragout',function(event){ // YOUR CODE });

EDIT: actually, I don't think it's dependent on jQuery, you can probably just use the code even without it.


Wow! Dragout is the ONE thing that worked for my layout with plenty of children elements firing dragleave even though I haven't left the parent dropzone.
After fighting with this issue for the last hour, dragout was the only solution that worked for me.
j
jeremie.b

My two cents: Hide a layer over your dropzone then show it when you dragenter, and target the dragleave on it.

Demo : https://jsfiddle.net/t6q4shat/

HTML

<div class="drop-zone">
  <h2 class="drop-here">Drop here</h2>
  <h2 class="drop-now">Drop now!</h2>
  <p>Or <a href="#">browse a file</a></p>
  <div class="drop-layer"></div>
</div>

CSS

.drop-zone{
  padding:50px;
  border:2px dashed #999;
  text-align:center;
  position:relative;
}
.drop-layer{
  display:none;
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  z-index:5;
}
.drop-now{
  display:none;
}

JS

$('.drop-zone').on('dragenter', function(e){
    $('.drop-here').css('display','none');
    $('.drop-now').css('display','block');
    $(this).find('.drop-layer').css('display','block');
    return false;
});

$('.drop-layer').on('dragleave', function(e){
    $('.drop-here').css('display','block');
    $('.drop-now').css('display','none');
    $(this).css('display','none');
    return false;
});

Simple and effective! I was going down the stopPropagation() route and I didn't like applying event handler to all children. It seemed messy but this works well and is simple to implement. Good idea.
B
Brad Larson

@hristo I have a much more elegant solution. Check that if that is something you could use.

Your effort was not wasted after all. I managed to use yours at first, but had different problems in FF, Chrome. After spending so many hours I got that suggestion working exactly as intended.

Here's how the implementation is. I also took advantage of visual cues to correctly guide users about the drop zone.

$(document).on('dragstart dragenter dragover', function(event) {    
    // Only file drag-n-drops allowed, http://jsfiddle.net/guYWx/16/
    if ($.inArray('Files', event.originalEvent.dataTransfer.types) > -1) {
        // Needed to allow effectAllowed, dropEffect to take effect
        event.stopPropagation();
        // Needed to allow effectAllowed, dropEffect to take effect
        event.preventDefault();

        $('.dropzone').addClass('dropzone-hilight').show();     // Hilight the drop zone
        dropZoneVisible= true;

        // http://www.html5rocks.com/en/tutorials/dnd/basics/
        // http://api.jquery.com/category/events/event-object/
        event.originalEvent.dataTransfer.effectAllowed= 'none';
        event.originalEvent.dataTransfer.dropEffect= 'none';

         // .dropzone .message
        if($(event.target).hasClass('dropzone') || $(event.target).hasClass('message')) {
            event.originalEvent.dataTransfer.effectAllowed= 'copyMove';
            event.originalEvent.dataTransfer.dropEffect= 'move';
        } 
    }
}).on('drop dragleave dragend', function (event) {  
    dropZoneVisible= false;

    clearTimeout(dropZoneTimer);
    dropZoneTimer= setTimeout( function(){
        if( !dropZoneVisible ) {
            $('.dropzone').hide().removeClass('dropzone-hilight'); 
        }
    }, dropZoneHideDelay); // dropZoneHideDelay= 70, but anything above 50 is better
});

you seem to be missing the definitions for some out of scope variables, I assume var dropZoneHideDelay=70, dropZoneVisible=true;
@TimoHuovinen yes, correct. Both dropZoneHideDelay, dropZoneVisible are needed across two 'on' document events in my implementation.
C
Community

This answer can be found here:

HTML5 dragleave fired when hovering a child element

var counter = 0;

$('#drop').bind({
    dragenter: function(ev) {
        ev.preventDefault(); // needed for IE
        counter++;
        $(this).addClass('red');
    },

    dragleave: function() {
        counter--;
        if (counter === 0) { 
            $(this).removeClass('red');
        }
    }
});

m
mortalis

My version:

$(".dropzone").bind("dragover", function(e){
    console.log('dragover');
});

$(".dropzone").bind("dragleave", function(e) {
  var stopDrag = false;
  if (!e.relatedTarget) stopDrag = true;
  else {
    var parentDrop = $(e.relatedTarget).parents('.dropzone');
    if (e.relatedTarget != this && !parentDrop.length) stopDrag = true;
  }

  if (stopDrag) {
    console.log('dragleave');
  }
});

With this layout:

<div class="dropzone">
  <div class="inner-zone">Inner-zone</div>
</div>

I've made a dump of element classes for e.target, e.currentTarget, e.relatedTarget for both dragover and dragleave events.

It showed me that on leaving the parent block (.dropzone) e.relatedTarget is not a child of this block so I know I'm out of the dropzone.


!e.relatedTarget worked perfectly for me. Thank you @mortalis
relatedTarget breaks in safari :(
E
Entretoize

Sorry it's javascript not jquery, but for me it's the most logical way to solve that. The browser should call dropleave (of the previous element) before dropenter (ofr the new element, as something can't enter something else before having leaved the forst thing, I don't understand why they did that ! So you just need to delay de dropleave like that:

function mydropleave(e)
{
    e.preventDefault();
    e.stopPropagation();

    setTimeout(function(e){ //the things you want to do },1);
}

And the dropenter will happen after the dropleave, that's all !


M
MMachinegun

So for me the approach pointer-events: none; didn't work too well... So here is my alternative solution:

    #dropzone {
        position: relative;
    }

    #dropzone(.active)::after {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        content: '';
    }

This way it is not possible to dragleave the parent (on a child) or dragover a child element. hope this helps :)

*The '.active'-class I add when I dragenter or dragleave. But if you're working without that just leave the class away.


I tried this in an EmberJS D&D component and adding the 'active' class programmatically is too slow about 40% of the time the mouse enters the parent div (ember-view). Not sure why. But leaving that off and it works great, so thank you for this simple solution. Tested on a Mac on latest versions (as of today) of Safari, Chrome, Firefox.
L
Luca Fagioli

I did not feel satisfied with any of the workarounds presented here, because I do not want to lose control over the children elements.

So I've used a different logic approach, translating it into a jQuery plugin, called jquery-draghandler. It does absolutely not manipulate the DOM, guaranteeing high performances. Its usage is simple:

$(document).ready(function() {

    $(selector).draghandler({
        onDragEnter: function() {
            // $(this).doSomething();
        },
        onDragLeave: function() {
            // $(this).doSomethingElse();
        }
    });

});

It deals flawlessly with the problem without compromising any DOM functionality.

Download, details and explanations on its Git repository.


How do I get the drag enter event in your plugin ?
I haven't actually tested your directive, but I think it does not work if the parent element (A) doesn't actually surround the element I want to check for (B). For example, if there is no padding between the bottom edge of B and the bottom edge of A, then dragenter will never be fired for element A, right?
@marcelj Element A can be the body document itself, so you do not really need a surrounding element (body does the job) with a minimum padding. The limitation I've found later with this approach is that if you work with frames and your element is at the border of it. In that case, I do not suggest this approach.
D
Dom Vinyard

Super simple quick fix for this, not tested extensively but works in Chrome right now.

Excuse the Coffeescript.

  dragEndTimer = no

  document.addEventListener 'dragover', (event) ->
    clearTimeout dragEndTimer
    $('body').addClass 'dragging'
    event.preventDefault()
    return no

  document.addEventListener 'dragenter', (event) ->
    $('section').scrollTop(0)
    clearTimeout dragEndTimer
    $('body').addClass 'dragging'

  document.addEventListener 'dragleave', (event) ->
    dragEndTimer = setTimeout ->
      $('body').removeClass 'dragging'
    , 50

This fixes the Chrome flicker bug, or at least the permutation of it that was causing me issues.


m
mefopolis

I'm actually liking what I see at https://github.com/lolmaus/jquery.dragbetter/ but wanted to share a possible alternative. My general strategy was to apply a background style to the dropzone (not its children) when dragentering it or any child of it (via bubbling). Then I remove the style when dragleaving the drop zone. Idea was when moving to a child, even if I remove the style from the dropzone when leaving it (the dragleave fires), I would simply reapply the style to the parent dropzone on dragentering any child. Problem is of course that when moving from the dropzone to a child of the dropzone, the dragenter gets fired on the child before the dragleave, so my styles got applied out of order. Solution for me was to use a timer to force the dragenter event back to the message queue, allowing me to process it AFTER the dragleave. I used a closure to access the event on the timer callback.

$('.dropzone').on('dragenter', function(event) {
  (function (event) {
    setTimeout(function () {
      $(event.target).closest('.dropzone').addClass('highlight');
    }, 0);
  }) (event.originalEvent); 
});

This seems to work in chrome, ie, firefox and works regardless of the number of children in the dropzone. I'm slightly uneasy about the timeout guaranteeing the resequencing of events, but it seems to work pretty well for my use case.


D
Diego T. Yamaguchi

Here, one of the simplest solution ●︿●

Take a look at this fiddle <-- try dragging some file inside the box

You can do something like this:

var dropZone= document.getElementById('box');
var dropMask = document.getElementById('drop-mask');


dropZone.addEventListener('dragover', drag_over, false);
dropMask.addEventListener('dragleave', drag_leave, false);
dropMask.addEventListener('drop', drag_drop, false);

By that you should already know whats happening here. Just take a look at the fiddle, you know.


P
Pao

I've had a similar problem and I fixed it this way:

The problem: The function drop(ev) is fired when the user drops an element in the "drop zone" (ul element), but, unfortunately, also when the element is dropped in one of its children ( li elements).

The fix:

function drop(ev) { 
ev.preventDefault(); 
data=ev.dataTransfer.getData('Text'); 
if(ev.target=="[object HTMLLIElement]")  
{ev.target.parentNode.appendChild(document.getElementById(data));}
else{ev.target.appendChild(document.getElementById(data));} 
} 

D
David A

I was trying to implement this myself for a file upload box where the box color would change when users dragged a file into the space.

I found a solution that is a nice mix of Javascript and CSS. Say you have a droppable zone with div with id #drop. Add this to your Javascript:

$('#drop').on('dragenter', function() {
    $(this).addClass('dragover');
    $(this).children().addClass('inactive');
});

$('#drop').on('dragleave', function() {
    $(this).removeClass('dragover');
    $(this).children().removeClass('inactive');
});

Then, add this to your CSS, to inactivate all children will class .inactive:

#drop *.inactive {
    pointer-events: none;
}

Thus, the children elements will be inactive for as long as the user is dragging the element over the box.


V
Vikrant

I was trying to implement this myself, and I did not want Jquery or any plugin either.

I wanted to handle the file upload, following way deemed best for me:

Files Structure:

--- /uploads {uploads directory}

--- /js/slyupload.js {javascript file.}

--- index.php

--- upload.php

--- styles.css {just a little styling..}

HTML Code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>my Dzone Upload...</title>
<link rel="stylesheet" href="styles.css" />
</head>

<body>
    <div id="uploads"></div>        
    <div class="dropzone" id="dropzone">Drop files here to upload</div>     
    <script type="text/javascript" src="js/slyupload.js"></script>      
</body>
</html>

Then This is the attached Javascript File:: 'js/slyupload.js'

<!-- begin snippet:  -->

<!-- language: lang-js -->

    // JavaScript Document

    //ondragover, ondragleave...


    (function(){        

        var dropzone = document.getElementById('dropzone');
        var intv;

        function displayUploads(data){
            //console.log(data, data.length);
            var uploads = document.getElementById('uploads'),anchor,x;

            for(x=0; x < data.length; x++){

                //alert(data[x].file);
                anchor = document.createElement('a');
                anchor.href = data[x].file;
                anchor.innerText = data[x].name;

                uploads.appendChild(anchor);
            }               
        }

        function upload(files){
            //console.log(files);
            var formData = new FormData(), 
                xhr      = new XMLHttpRequest(),    //for ajax calls...
                x;                                  //for the loop..

                for(x=0;x<files.length; x++){
                    formData.append('file[]', files[x]);

                    /*//do this for every file...
                    xhr = new XMLHttpRequest();

                    //open... and send individually..
                    xhr.open('post', 'upload.php');
                    xhr.send(formData);*/
                }

                xhr.onload = function(){
                    var data = JSON.parse(this.responseText);   //whatever comes from our php..
                    //console.log(data);
                    displayUploads(data);

                    //clear the interval when upload completes... 
                    clearInterval(intv);
                }                   

                xhr.onerror = function(){
                    console.log(xhr.status);
                }

                //use this to send all together.. and disable the xhr sending above...

                //open... and send individually..
                intv = setInterval(updateProgress, 50);
                xhr.open('post', 'upload.php');
                xhr.send(formData);

                //update progress... 
                 /* */                   
        }

        function updateProgress(){
            console.log('hello');
         }          

        dropzone.ondrop = function(e){
            e.preventDefault(); //prevent the default behaviour.. of displaying images when dropped...
            this.className = 'dropzone';
            //we can now call the uploading... 
            upload(e.dataTransfer.files); //the event has a data transfer object...
        }

        dropzone.ondragover = function(){
            //console.log('hello');
            this.className = 'dropzone dragover';
            return false;
        }

        dropzone.ondragleave = function(){
            this.className = 'dropzone';
            return false;
        }           
    }(window));

CSS:

body{ font-family:Arial, Helvetica, sans-serif; font-size:12px; } .dropzone{ width:300px; height:300px; border:2px dashed #ccc; color:#ccc; line-height:300px; text-align:center; } .dropzone.dragover{ border-color:#000; color:#000; }


A
Athena

Use the greedy : true to the child as a function of droppable. Then start only event clicked on the first layer.


关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now