John Talbot wrote:[color=blue]
> Very good link, this. Plenty of ideas there one can take. I'm still
> trying to figure out though how it detects which dropzone you're over.
>
>
> Aaron Gray wrote:[color=green]
>> Have a look at this :-
>>
>>
>>
http://openrico.org/rico/demos.page?...nd_drop_simple
>>
>> There's a bug in it though, if you scroll down the drag object appears
>> in the wrong place.[/color][/color]
When dragging, the position of the cursor is monitored and the
coordinates used to move the element being dragged and to and see if the
cursor is over a drop-zone.
Search for _updateDropZonesHover.
The function loops through all the dropzones and uses
_mousePointInDropZone to determine if the cursor is over a particular
drop zone.
The algorithm is not optimal - if there are lots of drop zones,
performance will degrade significantly. A better algorithm is to load
the drop zones into a btree or (better) a quadtree and just keep track
of the ones the cursor is over.
It may not make any difference for a small number of zones.
The demos at the link do not work properly in IE if it isn't
full-screen. If you are going to manually track what the cursor is
over, you have a lot of work ahead and it will likely only work in a
small subset of browsers.
A small plaything:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head><title>Drag Drop simple</title>
<meta http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1">
<style type="text/css">
body {margin:0;padding:0;}
..dropZone {width:100px;height:100px;border:2px solid blue;}
#dropZone-01 {position:absolute;top:100px;left:200px;}
#dropZone-02 {border-color:red;}
</style>
<script type="text/javascript">
var DragDrop = ( function() {
var docBody = document.body || document.documentElement;
var dZoneIndex = []; // References to drop zones
function dropZone(el){
this.el = el;
this.coords = getElRect(el);
}
function registerDZ(el){
dZoneIndex[dZoneIndex.length] = new dropZone(el);
}
function getElOffset(el){
var elXY = [0,0];
if (el.offsetParent) {
while (el.offsetParent) {
elXY[0] += el.offsetLeft;
elXY[1] += el.offsetTop;
el = el.offsetParent;
}
} else if (el.x){
elXY[0] = el.x;
elXY[1] = el.y;
}
return elXY;
}
function getElRect(el){
var pos = getElOffset(el);
pos[2] = pos[0] + el.offsetHeight;
pos[3] = pos[1] + el.offsetWidth;
return pos;
}
function cursorPos(e){
var e = e || window.event;
var posXY = [0,0];
if (e.pageX || e.pageY) {
posXY[0] += e.pageX;
posXY[1] += e.pageY;
} else if (e.clientX || e.clientY){
posXY[0] += e.clientX + document.body.scrollLeft;
posXY[1] += e.clientY + document.body.scrollTop;
}
return posXY;
}
function trackCursor(e){
var e = e || window.event;
var posXY = cursorPos(e);
var dz;
for (var i=0, n=dZoneIndex.length; i<n; ++i){
dz = dZoneIndex[i];
if ( pointInRect(posXY, dz.coords) ) {
dz.el.innerHTML = 'over';
dz.outline && (dz.outline.style.display = '');
} else {
dz.el.innerHTML = 'out';
dz.outline && (dz.outline.style.display = 'none');
}
}
}
function pointInRect(pos, rect){
return (
pos[0] > rect[0] && pos[0] < rect[2]
&& pos[1] > rect[1] && pos[1] < rect[3] );
}
return ({
registerZonesByClassname : function(cName){
var allEls = document.getElementsByTagName('*');
var el, i = allEls.length;
while (i--){
el = allEls[i];
if (el.className && el.className == cName){
registerDZ(el);
}
}
},
startTrackCursor : function() {
docBody.onmousemove = trackCursor;
},
stopTrackCursor : function() {
if (/\btrackCursor\b/.test(docBody.onmousemove)){
docBody.onmousemove = null;
}
var dz, i=0;
while( (dz = dZoneIndex[i++]) ){
dz.el.innerHTML = '';
}
},
showDropZones : function() {
var dz, i=0;
while( (dz = dZoneIndex[i++]) ){
dz.el.innerHTML += '<br>' + dz.coords;
}
}
});
})();
</script>
</head>
<body onload="
DragDrop.registerZonesByClassname('dropZone');
">
<input type="button" value="Start Track cursor" onclick="
DragDrop.startTrackCursor();
">
<input type="button" value="Stop track cursor" onclick="
DragDrop.stopTrackCursor();
">
<input type="button" value="Show zones" onclick="
DragDrop.showDropZones();
">
<div class="dropZone" id="dropZone-01"></div>
<div class="dropZone" id="dropZone-02"></div>
</body>
</html>
--
Rob