jQuery detect mousedown inside an element and then mouseup outside the element

别等时光非礼了梦想. 提交于 2019-11-29 06:18:29

问题


I have something similar to a drawing canvas, and I capture it's state on mouseup for undo purposes. The canvas isn't full screen, so you can draw with a brush and release outside the canvas. Something like this:

$("#element").mousedown(function(){
  $(document).mouseup(function(){
    //do something
  }); 
});

But this doesn't work of course. A plain $(document).mouseup doesn't work either, because I have many other UI elements and it saves the state each time you click on a UI element.

Any ideas?


回答1:


var isDown = false;

$("#element").mousedown(function(){
    isDown = true;
});

$(document).mouseup(function(){
    if(isDown){
        //do something
        isDown = false;
    }
}); 

For the sake of simplicity I put isDown in the global namespace. In production you would probably want to isolate the scope of that variable.




回答2:


The above answers will not work when text is selected.

The fix is to stop text from being selected when the mouse is down, and re-enable it when it's back up:

in your CSS:

.noselect {
    /* Prevent text selection */
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    user-select: none;
}

Then your JS:

var myButtonDown=false;

$('.ff', ffrw).mousedown(function() {
    myButtonDown=true;
    $('body').addClass('noselect');
    //Your code here
});

$(document).mouseup(function() {
    if (myButtonDown) {
        myButtonDown = false;
        $('body').removeClass('noselect');
    }
})



回答3:


Hopefully you find this little solution to be helpful. You can see it in action here: http://jsfiddle.net/neopreneur/PR2yE/

$(document).ready(function(){
    var startMouseDownElement = null;

    $('#element').mousedown(function(){
        // do whatever
        //...

        // set mousedown start element
        startMouseDownElement = $(this);
    });

    // handle bad mouseup
    // $('#container, #container *').mouseup would be more efficient in a busy DOM
    $('body *').mouseup(function(event){
        event.stopPropagation(); // stop bubbling
        if($(this).attr('id') != $(startMouseDownElement).attr('id')){
            //oops, bad mouseup
            alert('bad mouseup :(');  
        }
    });
});



回答4:


A possible implementation of mike's and waitingforatrain's answers in GWT. In the html head manage mouse up events (javascript code):

   var mouseUpHook = false;
   $(document).mouseup(function() {
       if (mouseUpHook) {
           mouseUpHook(null);
           mouseUpHook = false;
       }
   });

Let your custom Widget class implement MouseDownHandler and MouseUpHandler, and add those lines in your constructor to receive mouse events (java code):

    addDomHandler(this, MouseDownEvent.getType());
    addDomHandler(this, MouseUpEvent.getType());

Finally, add those methods in your custom Widget class (java and javascript code):

@Override
public void onMouseUp (MouseUpEvent event) {
    removeMouseUpHook();

    // ... do something else
}

private native void hookMouseUp () /*-{
    $wnd.$('body').addClass('noselect');
    var myThis = this;
    $wnd.mouseUpHook = function () {
        myThis.@your.custom.widget.class.full.qualified.Name::onMouseUp(Lcom/google/gwt/event/dom/client/MouseUpEvent;)(null);
    };
}-*/;

private native void removeMouseUpHook () /*-{
    $wnd.$('body').removeClass('noselect');
}-*/;

@Override
public void onMouseDown (MouseDownEvent event) {
    hookMouseUp();

    // ... do something else

    event.preventDefault();
}

Last line is usefull to prevent image dragging. Infact, user-select: none is not sufficent.




回答5:


If you've got a lot of clickable elements like I have, you're gonna want to create a global mouse catcher and set your mouseup code within the mousedowns of clicked element. Here's the code I used.

    var MouseCatcher=function()
    {
        this.init=function()
        {
            var mc = this; 
            $(document).bind({
                mouseup:function(e) 
                {
                    mc.mouseup();
                }
            });
        }
        this.mouseup=function()
        {
            return false;
        }
    }
    var mouseCatcher = new MouseCatcher();
    mouseCatcher.init();



    $('#clickableElement').bind({
        mousedown: function(e)
        {
            console.log('mousedown on element');

            mouseCatcher.mouseup=function()
            {
                console.log('mouseup called from MouseCatcher');
                this.mouseup = function(){return false;}
            }

        },
        mouseup:function(e)
        {
            //mouseup within element, no use here.
        }
    });


来源:https://stackoverflow.com/questions/4309912/jquery-detect-mousedown-inside-an-element-and-then-mouseup-outside-the-element

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!