Connecting Tech Pros Worldwide Forums | Help | Site Map

Ending drag&drop operation on mouse out of browser?

chris@chrisbeach.co.uk
Guest
 
Posts: n/a
#1: Oct 28 '05
I have a bit of JavaScript code (see below) that handles drag-and-drop
of elements on a webpage, simply moving them around the page.

The problem I'm having occurs when the user drags the object outside
the browser window and releases. The JavaScript onmouseup event fails
to fire (as is consistent with the language spec), and the element is
left in a "dragging limbo" - it follows the mouse cursor once it
returns inside the window (despite the button being up).

Can anyone think of any good ways of getting around this problem?
Ideally I'd want to fire the event attached to onmouseup when the
cursor left the browser window. Either that, or a more creative
solution if anyone can think of one

Your help would be much appreciated

Chris Beach

The following code is abridged:

var objPhoto;
var objDragged = null;
var mousePos = new Coords( 0, 0 );

function Photo( obj )
{
this.obj = obj;
var objOffset = obj;
this.coords = new Coords( 0, 0 );
while ( objOffset.offsetParent )
{
this.coords.y += objOffset.offsetTop;
this.coords.x += objOffset.offsetLeft;
objOffset = objOffset.offsetParent;
}
this.height = obj.height;
this.width = obj.width;
}

function Coords( x, y )
{
this.x = x;
this.y = y;
this.toString = function(){ return "x=" + this.x + ", y=" + this.y; }
}

function Arrow( user, coords )
{
var objArrowContainer = document.createElement( 'table' );
objArrowContainer.onmousedown = function(){ arrowMouseDown(
objArrowContainer );return false; }
document.body.appendChild( objArrowContainer );
}

function init()
{
objPhoto = new Photo( document.getElementById( "photo" ) );
var position = new Coords(
objPhoto.coords.x + objPhoto.width / 2,
objPhoto.coords.y + objPhoto.height / 2 );
var newArrow = new Arrow( new User( "Chris", "Chris", "cbicon.jpg" ),
position );
document.onmousemove = docMouseMove;
document.onmouseup = docMouseUp;
//document.onmouseover = function(){return false;}();
}

function arrowMouseDown( sender )
{
objDragged = sender;
return false;
}

function docMouseUp( e )
{
if ( objDragged == null ) return false;
docMouseMove( e );
var personCoords = new Coords(
parseInt( objDragged.style.left ) - ARROW_OFFSET.x -
objPhoto.coords.x,
parseInt( objDragged.style.top ) - ARROW_OFFSET.y - objPhoto.coords.y
);
objDragged = null;
objCoords = document.getElementById( "coords" );
objCoords.innerHTML = personCoords;
return false;
}

function docMouseMove( e )
{
if ( document.all )
{
mousePos.x = window.event.x;
mousePos.y = window.event.y;
if ( document.body && ( document.body.scrollLeft ||
document.body.scrollTop ) )
{
mousePos.x += document.body.scrollLeft;
mousePos.y += document.body.scrollTop;
}
else if ( document.documentElement &&
( document.documentElement.scrollLeft ||
document.documentElement.scrollTop ) )
{
mousePos.x += document.documentElement.scrollLeft;
mousePos.y += document.documentElement.scrollTop;
}
}
else if ( document.getElementById || document.layers )
{
mousePos.x = e.pageX;
mousePos.y = e.pageY;
}
if ( objDragged != null )
{
x = mousePos.x + ARROW_OFFSET.x;
y = mousePos.y + ARROW_OFFSET.y;

if ( x < objPhoto.coords.x + ARROW_OFFSET.x )
x = objPhoto.coords.x + ARROW_OFFSET.x;
else if ( x >= objPhoto.width + objPhoto.coords.x + ARROW_OFFSET.x )
x = objPhoto.width + objPhoto.coords.x + ARROW_OFFSET.x;

if ( y < objPhoto.coords.y + ARROW_OFFSET.y )
y = objPhoto.coords.y + ARROW_OFFSET.y;
else if ( y >= objPhoto.coords.y + objPhoto.height + ARROW_OFFSET.y )

y = objPhoto.height + objPhoto.coords.y + ARROW_OFFSET.y;

objDragged.style.left = x + 'px';
objDragged.style.top = y + 'px';
}
return false;
}


Mark Twain
Guest
 
Posts: n/a
#2: Oct 28 '05

re: Ending drag&drop operation on mouse out of browser?


Perhaps you could put a margin around the edge of the page with a
handler clearing the drag...? That's an old Flash trick. With Flash, if
you're fast enough, you can get past a reasonably sized margin without
the event firing, but JS is generally a bit faster.

In article <1130508086.197063.42620@f14g2000cwb.googlegroups. com>,
chris@chrisbeach.co.uk wrote:
[color=blue]
> I have a bit of JavaScript code (see below) that handles drag-and-drop
> of elements on a webpage, simply moving them around the page.
>
> The problem I'm having occurs when the user drags the object outside
> the browser window and releases. The JavaScript onmouseup event fails
> to fire (as is consistent with the language spec), and the element is
> left in a "dragging limbo" - it follows the mouse cursor once it
> returns inside the window (despite the button being up).
>
> Can anyone think of any good ways of getting around this problem?
> Ideally I'd want to fire the event attached to onmouseup when the
> cursor left the browser window. Either that, or a more creative
> solution if anyone can think of one
>
> Your help would be much appreciated
>
> Chris Beach
>
> The following code is abridged:
>
> var objPhoto;
> var objDragged = null;
> var mousePos = new Coords( 0, 0 );
>
> function Photo( obj )
> {
> this.obj = obj;
> var objOffset = obj;
> this.coords = new Coords( 0, 0 );
> while ( objOffset.offsetParent )
> {
> this.coords.y += objOffset.offsetTop;
> this.coords.x += objOffset.offsetLeft;
> objOffset = objOffset.offsetParent;
> }
> this.height = obj.height;
> this.width = obj.width;
> }
>
> function Coords( x, y )
> {
> this.x = x;
> this.y = y;
> this.toString = function(){ return "x=" + this.x + ", y=" + this.y; }
> }
>
> function Arrow( user, coords )
> {
> var objArrowContainer = document.createElement( 'table' );
> objArrowContainer.onmousedown = function(){ arrowMouseDown(
> objArrowContainer );return false; }
> document.body.appendChild( objArrowContainer );
> }
>
> function init()
> {
> objPhoto = new Photo( document.getElementById( "photo" ) );
> var position = new Coords(
> objPhoto.coords.x + objPhoto.width / 2,
> objPhoto.coords.y + objPhoto.height / 2 );
> var newArrow = new Arrow( new User( "Chris", "Chris", "cbicon.jpg" ),
> position );
> document.onmousemove = docMouseMove;
> document.onmouseup = docMouseUp;
> //document.onmouseover = function(){return false;}();
> }
>
> function arrowMouseDown( sender )
> {
> objDragged = sender;
> return false;
> }
>
> function docMouseUp( e )
> {
> if ( objDragged == null ) return false;
> docMouseMove( e );
> var personCoords = new Coords(
> parseInt( objDragged.style.left ) - ARROW_OFFSET.x -
> objPhoto.coords.x,
> parseInt( objDragged.style.top ) - ARROW_OFFSET.y - objPhoto.coords.y
> );
> objDragged = null;
> objCoords = document.getElementById( "coords" );
> objCoords.innerHTML = personCoords;
> return false;
> }
>
> function docMouseMove( e )
> {
> if ( document.all )
> {
> mousePos.x = window.event.x;
> mousePos.y = window.event.y;
> if ( document.body && ( document.body.scrollLeft ||
> document.body.scrollTop ) )
> {
> mousePos.x += document.body.scrollLeft;
> mousePos.y += document.body.scrollTop;
> }
> else if ( document.documentElement &&
> ( document.documentElement.scrollLeft ||
> document.documentElement.scrollTop ) )
> {
> mousePos.x += document.documentElement.scrollLeft;
> mousePos.y += document.documentElement.scrollTop;
> }
> }
> else if ( document.getElementById || document.layers )
> {
> mousePos.x = e.pageX;
> mousePos.y = e.pageY;
> }
> if ( objDragged != null )
> {
> x = mousePos.x + ARROW_OFFSET.x;
> y = mousePos.y + ARROW_OFFSET.y;
>
> if ( x < objPhoto.coords.x + ARROW_OFFSET.x )
> x = objPhoto.coords.x + ARROW_OFFSET.x;
> else if ( x >= objPhoto.width + objPhoto.coords.x + ARROW_OFFSET.x )
> x = objPhoto.width + objPhoto.coords.x + ARROW_OFFSET.x;
>
> if ( y < objPhoto.coords.y + ARROW_OFFSET.y )
> y = objPhoto.coords.y + ARROW_OFFSET.y;
> else if ( y >= objPhoto.coords.y + objPhoto.height + ARROW_OFFSET.y )
>
> y = objPhoto.height + objPhoto.coords.y + ARROW_OFFSET.y;
>
> objDragged.style.left = x + 'px';
> objDragged.style.top = y + 'px';
> }
> return false;
> }[/color]
chris@chrisbeach.co.uk
Guest
 
Posts: n/a
#3: Oct 28 '05

re: Ending drag&drop operation on mouse out of browser?


Thanks for your suggestion. How would you design such a margin (in
terms of HTML) such that it wouldn't affect the current look of the
page?

Mark Twain
Guest
 
Posts: n/a
#4: Oct 28 '05

re: Ending drag&drop operation on mouse out of browser?


In article <1130515635.251029.80210@f14g2000cwb.googlegroups. com>,
chris@chrisbeach.co.uk wrote:
[color=blue]
> Thanks for your suggestion. How would you design such a margin (in
> terms of HTML) such that it wouldn't affect the current look of the
> page?[/color]

That doesn't affect the look of the page? Geez, I have no clue. I start
thinking about it and it gets very kludgy in my head very fast -- stuff
like a div with no background, but you'd need something to hold it open,
like a transparent gif. And then you'd need to calculate the height of
the page so you'd know how big the gif should be... etc.

Maybe I'll just stand aside and wait for someone to offer a better
solution.
Mario Klaue
Guest
 
Posts: n/a
#5: Oct 28 '05

re: Ending drag&drop operation on mouse out of browser?


put something similar to the following code in the IE branch of your
mouseMove handler:

if(window.event.button != 1)
docMouseUp(evt);

Sorry, but I have no solution for the other browsers.

Please, note also that my drag & drop code attaches/detaches the mouseMove
handler on mouseDown/mouseUp. I guess you have to check the existance of
objDragged as condition expression in the above code fragment.


chris@chrisbeach.co.uk
Guest
 
Posts: n/a
#6: Oct 31 '05

re: Ending drag&drop operation on mouse out of browser?


Thanks for your suggestion. Cross-browser support is quite important to
me, especially as I developing on a Mac.

I have solved the problem temporarily by setting a timeout on the drop
operation

Chris

Closed Thread