John Talbot wrote:
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: 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.
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