6

I have bound dragenter event on an object that contains some children.

$(document).on('dragenter', '#container', function(e) {
  console.log('dragenter');
});

When I move with dragged file around them, this event is firing repeatedly. What I have expected is firing dragenter only when entering #container element, not every child too.

Is it proper behavior? How can I prevent it?

kaiz.net
  • 1,984
  • 3
  • 23
  • 31
hsz
  • 148,279
  • 62
  • 259
  • 315

3 Answers3

12

You can test whether the element that triggered the event is the container:

var container = $('#container').get(0);

$(document).on('dragenter', '#container', function(event) {
  if(event.target === container) {
      console.log('dragenter');
  }
});

Or if you don't have to use event delegation:

$('#container').on('dragenter', function(event) {
    if(event.target === this) {
        console.log('dragenter');
    }  
});
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 1
    Unfortunately in case when `#container` is fully covered with its children this test always fails. Is not it possible to not bind children with `dragend` - just `#container` ? – hsz Apr 24 '12 at 12:21
  • Ok, I got rid of this using your answer. However I'm stil curious about binding just parent with an event. ;-) Thank you! – hsz Apr 24 '12 at 12:31
1

try to add stopPropagation

$(document).on('dragenter', '#container', function(e) {
  e.stopPropagation();
  console.log('dragenter');
});
bart s
  • 5,068
  • 1
  • 34
  • 55
  • use $('#container') as selector instead of $(document) – bart s Apr 24 '12 at 12:12
  • I have to do it this way because I need live behavior of `on`. – hsz Apr 24 '12 at 12:13
  • the documentation states that the event bubbles up from the '#container' to the selector $(document). In your case the expected behaviour is different from real and you need to filter yourself (as far as I can see) (see Felix' answer) – bart s Apr 24 '12 at 12:25
0

My answer to this question is to use event capturing instead of event bubbling.

In a nutshell, event capturing "trickles down" from the outer element, to the source element or until e.stopPropagation() is called.

Event bubbling bubbles events up from the source element up through parents until it reaches the document or is stopped with e.stopPropagation().

So, to apply to drag enter, you want the outer div to handle the event, even though it is actually the inner div that is generating the event.

Using event capturing make the ondragenter fire in the Outer Div before the inner div. In the outter div event handler, you call e.stopPropagation. So the inner div event handler never actually runs.

This is how to use jquery to capture the event:

$("#outerDiv").get(0).addEventListener("ondragenter", function(e){e.stopPropagation()}, true);

Note the last parameter.

Community
  • 1
  • 1
Greg Gum
  • 33,478
  • 39
  • 162
  • 233