471,073 Members | 1,130 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,073 software developers and data experts.

when draging a <div>, how can I detect what I'm moving over?

I'm playing with dragable <DIV>s, being inspired by google.com/ig,
where you can move items on the page around and have items you move
over change position if necessary.

I have 3 div's setup, one for each dragable item (boxes about
100x150px), inside another div that sets up a border.

my script is instigated by an onMouseOver event and works great for
moving items, setting the opacity, etc. The only trouble is (and I
guess I should have expected this) is that when I'm dragging one div,
the onMouseOver events for the other 2 divs are not initialized. In
retrospect that's probably a good thing, or I'd end up dragging
everything at the same time.

What I'm looking for is an idea where to go next in order to find out
what I'm dragging a div over. I purposely didn't include any code as
I'm really looking for just hints rather than solutions, as this
project is very much a learning excercise for myself, and I've already
cheated enough by downloading dom-drag.js as the base code.

any ideas how I can find out what I'm dragging over? My thoughts were
listeners (though I don't know much about them but they seemed to make
sense here) or not worrying about what I'm over, but more where I am in
the list and then work out if something needs to be move or not (seems
cumbersome and potentially a resource hog while I check mouse movements
and positions while dragging)

any hints and/or tips would be appreciated.

Nov 11 '05 #1
12 2192
Kevin Blount wrote:
What I'm looking for is an idea where to go next in order to find out
what I'm dragging a div over. I purposely didn't include any code as
I'm really looking for just hints rather than solutions, as this
project is very much a learning excercise for myself, and I've already
cheated enough by downloading dom-drag.js as the base code.


I really like your attitude :) However, it does not hurt to
read source code of others, instead it helps you to understand
to write it yourself, and probably better.

Look into the `ondragover' event handler for IE:

<http://msdn.microsoft.com/workshop/author/dhtml/reference/events/ondragover.asp>

I don't know if it is supported in the Gecko DOM as well, probably
not as the reference does not mention it. However, there are the
onmouse* event handlers which could be and are probably used for this.

<http://developer.mozilla.org/en/docs/DOM:element#Event_Handlers>
HTH

PointedEars
Nov 23 '05 #2
thanks for the response.. I'll definitely check out the ondragover..
sounds ideal (though no clue exactly what it does yet <g>), and thanks
for the DOM references too.

Nov 23 '05 #3
> I really like your attitude :) However, it does not hurt to
read source code of others, instead it helps you to understand
to write it yourself, and probably better.


Its a pritty tough act to follow, very criptic, I've tried three times to
look at it so far.

Anyone got a JavaScript reformatter or pritty printer of any kind ?

I'll have another butchers at it at some point.

Aaron
Nov 23 '05 #4
Aaron Gray wrote:

Please provide proper attribution.
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
I really like your attitude :) However, it does not hurt to
read source code of others, instead it helps you to understand
to write it yourself, and probably better.


Its a pritty tough act to follow, very criptic, I've tried three times to
look at it so far.

Anyone got a JavaScript reformatter or pritty printer of any kind ?


When Pretty Printing is needed, I use the Format feature of the JavaScript
Editor PlugIn for Eclipse from <http://sourceforge.net/projects/jseditor/>.

IIRC Macromedia Dreamweaver MX also includes such a feature and probably
many other JS editors.
PointedEars
Nov 23 '05 #5
>> Anyone got a JavaScript reformatter or pritty printer of any kind ?

When Pretty Printing is needed, I use the Format feature of the JavaScript
Editor PlugIn for Eclipse from
<http://sourceforge.net/projects/jseditor/>.


Ah, Eclipse, I keep meaning to download it and try it out, never seem to get
round to it though.

Aaron
Nov 23 '05 #6
Scriptaculous does it at this page: http://script.aculo.us/demos/shop ,
yet I still can't understand how they do it.

If someone can find out, please tell...

Thanks.

Thomas 'PointedEars' Lahn wrote:
Kevin Blount wrote:
What I'm looking for is an idea where to go next in order to find out
what I'm dragging a div over. I purposely didn't include any code as
I'm really looking for just hints rather than solutions, as this
project is very much a learning excercise for myself, and I've already
cheated enough by downloading dom-drag.js as the base code.


I really like your attitude :) However, it does not hurt to
read source code of others, instead it helps you to understand
to write it yourself, and probably better.

Look into the `ondragover' event handler for IE:

<http://msdn.microsoft.com/workshop/author/dhtml/reference/events/ondragover.asp>

I don't know if it is supported in the Gecko DOM as well, probably
not as the reference does not mention it. However, there are the
onmouse* event handlers which could be and are probably used for this.

<http://developer.mozilla.org/en/docs/DOM:element#Event_Handlers>
HTH

PointedEars

Nov 23 '05 #7
> Scriptaculous does it at this page: http://script.aculo.us/demos/shop ,
yet I still can't understand how they do it.

If someone can find out, please tell...


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.

There's more goodies at :-

http://en.wikipedia.org/wiki/AJAX

Hope that helps.

Aaron
Nov 23 '05 #8
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.

Nov 23 '05 #9
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
Nov 23 '05 #10
re4:Aaron - thanks for the link to that example. It looks just what I
need to rip apart for clues :)

re4: RobG - and thanks for pointing out the part to look for, and for
the example of mouse tracking

Nov 23 '05 #11
RobG: just to let you know, and anyone else that wants to use this
incredibly useful example, I found a small bug in the code above.

I made some change for testing, putting dropzone 1 directly above
dropzone 2, as you might see in a websites side menu. When the width
and height were the same (100px in your code) this works perfectly, but
if I increased the width to 150px (height still at 100px) then it was
possible to have both dropzones as 'over' when the cursor was hoving
around the top of dropzone 2.

I found the fix in the function below:

function getElRect(el){
var pos = getElOffset(el);
pos[2] = pos[0] + el.offsetHeight;
pos[3] = pos[1] + el.offsetWidth;
return pos;
}

I had to transpose offsetHeight and offsetWidth to get the right
results, i.e.

function getElRect(el){
var pos = getElOffset(el);
pos[2] = pos[0] + el.offsetWidth;
pos[3] = pos[1] + el.offsetHeight;
return pos;
}

I hope you don't mind me pointing this out publically. I personally
found this example to be extremely useful, and would definitely
recommend people come here if they are trying to do what I'm working
on, and figured they should know about this too.

cheers

Nov 23 '05 #12
Kevin Blount wrote:
RobG: just to let you know, and anyone else that wants to use this
incredibly useful example, I found a small bug in the code above.

I made some change for testing, putting dropzone 1 directly above
dropzone 2, as you might see in a websites side menu. When the width
and height were the same (100px in your code) this works perfectly, but
if I increased the width to 150px (height still at 100px) then it was
possible to have both dropzones as 'over' when the cursor was hoving
around the top of dropzone 2.

I found the fix in the function below:

function getElRect(el){
var pos = getElOffset(el);
pos[2] = pos[0] + el.offsetHeight;
pos[3] = pos[1] + el.offsetWidth;
return pos;
}

I had to transpose offsetHeight and offsetWidth to get the right
results, i.e.

function getElRect(el){
var pos = getElOffset(el);
pos[2] = pos[0] + el.offsetWidth;
pos[3] = pos[1] + el.offsetHeight;
return pos;
}

I hope you don't mind me pointing this out publically.


Eeee gad - me, a mistake? Aggghh!! Crikey, *that* has never happened
before!! :=x

I posted it, so I'll happily cop consequences.

I hadn't tested with non-square shapes (but I have now). The use of an
array makes it much more likely that such a mistake would be made, an
object is probably more appropriate (I'm not using any of an array's
specialness) so slap-my-wrist.

An object with named properties would be less prone to such error (but
not foolproof):

function getElRect(el){
var elTL = getElOffset(el);
var elRect = {left:elTL.x, top:elTL.y, bottom:0, right:0};
elRect.right = elRect.left + el.offsetWidth;
elRect.bottom = elRect.top + el.offsetHeight;
return elRect;
}
With appropriate changes to other bits as well.

[...]
--
Rob
Nov 23 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Steve Klett | last post: by
1 post views Thread by sid | last post: by
nathj
5 posts views Thread by nathj | last post: by
2 posts views Thread by bgold12 | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.