I\'m making extensive use of the HTML5 native drag & drop, and it\'s almost entirely behaving itself, with one small exception.
I\'m trying to highlight my dropzones
I may be getting overly complex here but I would do something like this:
var draggingFile = false;
var event2;
//elements with the class hotspots are OK
var hotspots = $(".hotspots");
//Handlers on the body for drag start & stop
$("body").live("dragover", function(event){ draggingFile = true; event2 = event; });
$("body").live("dragexit dragleave drop", function(event){ draggingFile = false; event2 = event; });
//Function checks to see if file is being dragged over an OK hotspot regardless of other elements infront
var isTargetOK = function(x, y){
hotspots.each(function(i, el){
el2 = $(el);
var pos = el2.offset();
if(x => pos.left && x <= pos.left+el2.width() && y => pos.top && y <= post.top+el2.height()){
return true;
}
});
return false;
};
//Mousemove handler on body
$("body").mousemove(function(e){
//if user is dragging a file
if(draggingFile){
//Check to see if this is an OK element with mouse X & Y
if(isOKTarget(e.pageX, e.pageY)){
//Light em' up!
lightdz(event2);
} else { /* Fade em' :( */ dimdz(event2); }
} else {
dimdz(); //Having no parematers means just makes sure hotspots are off
}
});
BTW that's probably not going to work straight off the bat, so you'll have to tweak it a bit to work with your code.
I'm genuinely embarrassed by how easy this one was.
$("*:visible").live('dragenter dragover',function(event){lightdz(event)});
$("#page").live('dragleave dragexit',function(event)
{
if(event.pageX == "0")
dimdz(event);
});
$("*:visible").live('drop',function(event){dimdz(event)});
#page is a page-wide container. If the dragleave event takes the dragged object outside of the browser window, event.pageX will have a value of 0. If it happens anywhere else, it'll have a non-zero value.
I tried the accepted solution here, but ended up using setTimeout to overcome the issue. I was having a ton of trouble with the page-wide container blocking the drop element if it was floated on top, and still causing the problem if it was the drop element.
<body style="border: 1px solid black;">
<div id="d0" style="border: 1px solid black;"> </div>
<div id="d1" style="border: 1px solid black; display: none; background-color: red;">-> drop here <-</div>
<div id="d2" style="border: 1px solid black;"> </div>
<div style="float: left;">other element</div>
<div style="float: left;"> - </div>
<div style="float: left;">another element</div>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
</body>
<script type="text/javascript">
var resetTimer;
var f = function(e)
{
if (e.type == "dragover")
{
e.stopPropagation();
e.preventDefault();
if (resetTimer)
{
clearTimeout(resetTimer);
}
document.getElementById('d1').style.display = '';
}
else
{
var f = function()
{
document.getElementById('d1').style.display = 'none';
};
resetTimer = window.setTimeout(f, 25);
}
};
document.body.addEventListener("dragover", f, true);
document.body.addEventListener("dragleave", f, true);
document.getElementById('d1').addEventListener("drop", function(e){ f(); alert('dropped'); }, false);
</script>
If you were to just call f();
instead of window.setTimeout(f, 250);
, you'll see some nasty flickering of the element showing and hiding.
http://jsfiddle.net/guYWx/