1

Overview

I want to attach an event to an element for handling file drag and drop events, but it seems like this event is also being attached to all the child elements. For example,

$('#dragtarget').on('dragenter', function() {
    console.log('dragenter');
});

... if I drag files over any elements that are children of the #dragtarget element, the console will output dragenter. So if I attach this event to document or window, the event will fire when hovering over any element on the page.

The same thing happens with dragleave, except when leaving child elements.

Question

Why is this happening? Is there away to attach this event to only the element intended? If not, is there a way to detach the event from all child elements?

jsFiddle

Here's an example fiddle to tinker with: http://jsfiddle.net/UnsungHero97/ePLV6/7/

  • Notice how the border changes to solid when you drag files over the box, but back to dashed when hovering over the text

  • I want the border to change to solid when dragging files over the box, no matter if I'm hovering over the text within the box

Here's the code from the fiddle for just in case:

HTML

<div id="dragtarget">
    <span>File over/out here</span>
    <br/><br/>
    <span>more text here</span>
</div>

JS

// I expect only the #dragtarget element to fire the 'dragenter' and 'dragleave' events,
// not the child elements
$('#dragtarget').on('dragenter', function() {

    $(this).css({borderStyle: 'solid'});

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

}).on('dragleave', function() {

    $(this).css({borderStyle: 'dashed'});

    event.stopPropagation();
    event.preventDefault();
    return false;
});
Hristo
  • 45,559
  • 65
  • 163
  • 230

1 Answers1

2

It doesn't. You're probably seeing event bubbling. Check the event.target to see where the event you're handling originated.

robertc
  • 74,533
  • 18
  • 193
  • 177
  • I don't think that's the issue. I changed the code to stop the event from propagating and nothing changed. – Hristo Jun 04 '12 at 02:53
  • Can you show us the modified code? Because this certainly looks like event bubbling. – Gaurav Shetty Jun 04 '12 at 03:13
  • @GauravShetty... it's in the jsFiddle, but I've updated my post to include it – Hristo Jun 04 '12 at 03:27
  • @Hristo But you do want it to propogate, you just don't want to flip the border style if the event is fired going out of the div in to the spans. Check out [HTML5 dragleave fired when hovering a child element](http://stackoverflow.com/questions/7110353/html5-dragleave-fired-when-hovering-a-child-element/7115883#7115883). – robertc Jun 04 '12 at 10:21
  • the problem is knowing when a `dragleave` event is fired going out of the spans... the `relatedTarget` solution there is not cross-browser compatible – Hristo Jun 04 '12 at 14:00
  • I just noticed you answered the question you linked to... is there something I'm missing? if `relatedTarget` isn't specified, how will I know `dragleave` fires for a child element without checking against each child? – Hristo Jun 04 '12 at 14:09
  • 1
    @Hristo I don't have a good answer for you there, sometimes things just suck – robertc Jun 04 '12 at 14:12
  • :D well I'll keep thinking about it and if I come up with a solution I'm happy with, I'll post back. However, this doesn't answer my original question... why is the event I'm attaching to the element also get attached to the children? – Hristo Jun 04 '12 at 14:17
  • @Hristo The answer to your original question is the answer we're both commenting on – robertc Jun 04 '12 at 14:58