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]