Ending drag&drop operation on mouse out of browser?

Discussion in 'Javascript' started by chris@chrisbeach.co.uk, Oct 28, 2005.

  1. Guest

    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;
    }
     
    , Oct 28, 2005
    #1
    1. Advertising

  2. Guest

    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?
     
    , Oct 28, 2005
    #2
    1. Advertising

  3. Mario Klaue Guest

    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.
     
    Mario Klaue, Oct 28, 2005
    #3
  4. Guest

    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
     
    , Oct 31, 2005
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Oliver Klein
    Replies:
    0
    Views:
    704
    Oliver Klein
    Aug 24, 2003
  2. T
    Replies:
    0
    Views:
    383
  3. olimoli

    cross browser window drag & drop

    olimoli, Nov 5, 2003, in forum: Javascript
    Replies:
    1
    Views:
    95
  4. Kirk Is
    Replies:
    0
    Views:
    223
    Kirk Is
    May 10, 2005
  5. Louis

    Mouse Drag-and-drop Problem

    Louis, Oct 16, 2007, in forum: Javascript
    Replies:
    2
    Views:
    126
    Thomas 'PointedEars' Lahn
    Oct 16, 2007
Loading...

Share This Page