C
chris
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;
}
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;
}