The root cause of the problem is that your code is setting up a feedback loop. In Firefox at least.
When any ondragenter
event propagates to your body
element you code modifies the displayed text by setting the element's innerHTML
property. The browser updates the element in the DOM, and in the case of Firefox sees that you're dragging something over the updated element and retriggers the ondragenter
event (which then propagates back up to your body
element and restarts the whole process).
To fix that, all you have to do is pull one link out of the chain to break the feedback loop. For instance, by tracking whether or not you've already changed the text for a given 'drag' event (essentially as Adam Shaver suggests), or by checking to see if the text already says "Drop it Here!" before assigning to the innerHTML
property, etc..
Though be careful with that approach if you want to have your handler work across multiple 'drag' events (i.e. have the text toggle back and forth between "Drop file somewhere here." and "Drop it here!" whenever the user starts a 'drag' operation and then cancels/ends it without dropping the file). You'll have to run your accounting correctly on both ends if you want that to work.
Another option to break the feedback loop is to cancel the events triggered by the text element so that they don't propagate up to body
in the first place. For instance, like:
<h1 class="cover-heading" id="promo-text" ondragenter="cancelEvent(event);">Drop file somewhere here.</h1>
[...]
function cancelEvent(evt) {
if (! evt) {
evt = window.event;
}
if (evt) {
console.log("Canceling event");
evt.cancelBubble = true;
if (evt.stopImmediatePropagation) {
evt.stopImmediatePropagation();
}
}
return false;
}
http://jsfiddle.net/j7u6hLyj/2/
That may work better based upon your current setup, as it's less manual bookkeeping to worry about.
Other approaches might also work, such as inspecting the event's target
(or srcElement
on IE). Essentially anything that breaks the feedback loop will do.