custom dragDrop using onmousedown, onmouseup

J

jon

Hello,
I'm trying to experiment with some javascript to do some custom
dragdrop handling. I wish to use the onMouseDown event to trigger the
start of my drag, and onMouseup for a potentential drop. I hope to
turn on the onmouseup only in onmousedown. And eventually go one step
further and incorporate onmousemove for a true drag workflow.

I'm running into a problem however, where after mousedown, mouseup will
not fire when I release the mouse button. It will however fire if I
click again. So the event isn't being tracked until I release the
mouse the first time apparently. Which ruins my dragDrop of course.

Below is the code. You can see a move() method that would incorporate
onmousemove, but for the most basic test I'm just using beginDrag and
endDrag.

Any ideas why onmouseup won't fire until I release the button, then
click again?

thanks




--------------

<table cellpadding="0" cellspacing="5" border="1">
<tr id="contentTr1">
<td id="image_1_td" >
<img id="image_1_img" src="cat1.jpg"
onMouseDown="beginDrag(event, this, this.id)">
</td>
<td id="image_2_td">
<img id="image_2_img" src="cat2.jpg"
onMouseDown="beginDrag(event, this, this.id)">
</td>
</tr>
</table>

--------------
var beginX = null;
var beginY = null;

function beginDrag(event, obj, id) {
beginX = event.clientX;
beginY = event.clientY;

window.status = 'beginDrag';
top.drag_id = id;

//document.onmousemove = function() { move(event, obj, id); };
document.onmouseup = function() {
window.status='onmouseup frame1';
endDrag(event);
top.frame1.document.onmousemove=null;
top.frame1.document.onmouseup=null;
top.drag_id = null;
};
}

function move(event, obj, id) {
if(beginX == null){ return; }

window.status = 'drag started: ' + event.clientX + ', ' +
event.clientY + ', onmouseup set and waiting...';
top.drag_id = id;

document.onmouseup = function() {
window.status='onmouseup frame1';
top.frame1.document.onmousemove=null;
top.frame1.document.onmouseup=null;
top.drag_id = null;
};
}

function endDrag(event) {
if(top.drag_id != null){
window.status = 'drop handled: ' + top.drag_id;
return true;
} else {
return false;
}
}
 
J

jon

I'm aware of the libs and have used yahoo's library on other sites. It
works well.

I'm trying to implement a multi-frame solution now, and yahoo's lib
doesn't easily convert to that. Before I undertake attempting to
convert it, I'd like to understand the basics a bit more.

My original question still stands.
 
J

jon

I investigated the original problem some more and have found that for
some reason dragging an image within a page fires only a mousedown
event. After the drag is moving, if the small "line through a circle"
cursor appears then there is no mousemove or mouseup event fired
subsequently. Any ideas how one might avoid that?
 
N

naixn

jon wrote :
I investigated the original problem some more and have found that for
some reason dragging an image within a page fires only a mousedown
event. After the drag is moving, if the small "line through a circle"
cursor appears then there is no mousemove or mouseup event fired
subsequently. Any ideas how one might avoid that?

Why don't you try to put the image in a <div>, and make that <div> draggable,
instead of the image? :)
 
P

pcx99

jon said:
I'm running into a problem however, where after mousedown, mouseup will
not fire when I release the mouse button. It will however fire if I
click again. So the event isn't being tracked until I release the
mouse the first time apparently. Which ruins my dragDrop of course.

Your event handlers are not returning "false". When you set up a
handler the browser will call your code and if control is passed back to
the browser without the result being false the browser will continue its
default behavior. So whenever you actually DO something inside your
event handlers you MUST return false or the browser will continue to do
its own thing, at the expense of your sanity ;)
function beginDrag(event, obj, id) {
beginX = event.clientX;
beginY = event.clientY;

window.status = 'beginDrag';
top.drag_id = id;

//document.onmousemove = function() { move(event, obj, id); };
document.onmouseup = function() {
window.status='onmouseup frame1';
endDrag(event);
top.frame1.document.onmousemove=null;
top.frame1.document.onmouseup=null;
top.drag_id = null;
};
}

function beginDrag(event, obj, id) {
beginX = event.clientX;
beginY = event.clientY;

window.status = 'beginDrag';
top.drag_id = id;

//document.onmousemove = function() { move(event, obj, id); };
document.onmouseup = function() {
window.status='onmouseup frame1';
endDrag(event);
top.frame1.document.onmousemove=null;
top.frame1.document.onmouseup=null;
top.drag_id = null;
};

return false;
}


Hope that helps you out a bit.
 
J

jon

Thanks for the comments.
The returning false I think was a good around bet.

Some things I learned that helped along with the comments:
1) Dragging an image only fires an onmousedown event, not an
onmousemove or onmouseup after.
So I put the image as a background-image on a table cell, and drag
the table cell. This way we aren't dragging an image directly.
2) Dragging a table cell with a background image _sometimes_ still
thinks it's dragging an image, I think only on the 2nd+ times if it has
focus on the cell.
Putting an empty div, full height/width in the cell seems to mask
and prevent this.
3) Putting an empty div in the cell causes the table to highlight on
any drag and thus hides all the images with highlighting of empty
space.
Disabling of all text selection stops this nicely.
4) Sometimes onmouseup won't fire in an alternate frame than where the
onmousedown was set, and onmousemove event doesn't know it crossed into
the new frame until mouse is released.
Simple solution is to track global mouse coordinates and know that
if coordinates reach certain part of the window (ie, bottom 90% for
me), then it is in the secondary frame, despite the event's confusion.
 
P

pcx99

jon said:
Thanks for the comments.
The returning false I think was a good around bet.

Some things I learned that helped along with the comments:
1) Dragging an image only fires an onmousedown event, not an
onmousemove or onmouseup after.
So I put the image as a background-image on a table cell, and drag
the table cell. This way we aren't dragging an image directly.
2) Dragging a table cell with a background image _sometimes_ still
thinks it's dragging an image, I think only on the 2nd+ times if it has
focus on the cell.
Putting an empty div, full height/width in the cell seems to mask
and prevent this.
3) Putting an empty div in the cell causes the table to highlight on
any drag and thus hides all the images with highlighting of empty
space.
Disabling of all text selection stops this nicely.
4) Sometimes onmouseup won't fire in an alternate frame than where the
onmousedown was set, and onmousemove event doesn't know it crossed into
the new frame until mouse is released.
Simple solution is to track global mouse coordinates and know that
if coordinates reach certain part of the window (ie, bottom 90% for
me), then it is in the secondary frame, despite the event's confusion.

You're hitting all the problems with #1-#4 because your event handlers
are not doing a "return false" before they end. That means the browser
continues with it's default behavior which interferes with what you want
to do with your code (forcing you to "hide" the image behind table-cells
for instance).

If you leave the browser completely alone (example: web page has a
single image, no javascript, no nothing) and you click on an image and
drag it the mouse will change into a no sign (circle with a slash
through it), if you keep dragging outside your browser the mouse will
change indicating you can drop the image on your desktop (or into an
application which can process images). This is the default behavior.

When you don't "return false" in your handlers this is what the browser
is trying to do. When your handlers start returning false the browser
will stop behaving this way and stop interfering with your code :)
 
J

jon

I wish this were the case, but in practice "return false" did not solve
most of these problems...
 
P

pcx99

jon said:
I wish this were the case, but in practice "return false" did not solve
most of these problems...

With the exception of #4, #1-#3 are all workarounds for not returning
false in your event handlers. (I haven't tested #4 so it may be fixed
as well), but as for moving images...

Here's a working example of a raw naked image being that can be dragged
and dropped on demand from the user.

http://www.hunlock.com/examples/dragdroppic.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top