jQuery在元素内部检测mousedown,然后在元素外部进行mouseup

时间:2010-11-30 02:05:17

标签: javascript jquery event-handling

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

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

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

有什么想法吗?

5 个答案:

答案 0 :(得分:34)

var isDown = false;

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

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

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

答案 1 :(得分:7)

选择文字时,上述答案无效。

修复方法是在鼠标停止时停止选择文本,并在备份时重新启用它:

你的CSS中的

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

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

答案 2 :(得分:2)

希望您能找到这个小小的解决方案。你可以在这里看到它: 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 :(');  
        }
    });
});

答案 3 :(得分:0)

在GWT中可能实现迈克和waitingforatrain的答案。 在html头管理鼠标注册事件(javascript代码):

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

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

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

最后,在自定义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 () {
        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();
}

最后一行有助于防止图像拖动。事实上,用户选择:none是不够的。

答案 4 :(得分:0)

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

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