Javascript jQuery检测元素内的mousedown,然后检测元素外的mouseup

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4309912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 11:50:17  来源:igfitidea点击:

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

javascriptjqueryevent-handling

提问by methodofaction

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:

我有一些类似于绘图画布的东西,为了撤消目的,我在 mouseup 上捕获了它的状态。画布不是全屏的,因此您可以使用画笔进行绘制并在画布外释放。像这样的东西:

$("#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.

但这当然行不通。普通的 $(document).mouseup 也不起作用,因为我有许多其他 UI 元素,并且每次单击 UI 元素时它都会保存状态。

Any ideas?

有任何想法吗?

回答by mike

var isDown = false;

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

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

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

为了简单起见,我放入isDown了全局命名空间。在生产中,您可能希望隔离该变量的范围。

回答by bcoughlan

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:

在你的 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:

然后你的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');
    }
})

回答by Nick G

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

希望这个小解决方案对您有所帮助。你可以在这里看到它的实际效果: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 :(');  
        }
    });
});

回答by makeroo

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

GWT 中迈克和waitforatrain 答案的可能实现。在 html head 中管理鼠标向上事件(javascript 代码):

   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):

让您的自定义 Widget 类实现 MouseDownHandler 和 MouseUpHandler,并将这些行添加到您的构造函数中以接收鼠标事件(java 代码):

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

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

最后,在您的自定义 Widget 类(java 和 javascript 代码)中添加这些方法:

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

    // ... do something else
}

private native void hookMouseUp () /*-{
    $wnd.$('body').addClass('noselect');
    var myThis = this;
    $wnd.mouseUpHook = function () {
        [email protected]::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.

最后一行有助于防止图像拖动。事实上, user-select: none 是不够的。

回答by louisinhongkong

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.

如果你有很多像我一样的可点击元素,你会想要创建一个全局鼠标捕捉器并在被点击元素的 mousedowns 中设置你的 mouseup 代码。这是我使用的代码。

    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.
        }
    });