【问题标题】:jQuery detect mousedown inside an element and then mouseup outside the elementjQuery在元素内检测mousedown,然后在元素外检测mouseup
【发布时间】:2010-11-30 02:05:16
【问题描述】:

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

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

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

有什么想法吗?

【问题讨论】:

    标签: javascript jquery event-handling


    【解决方案1】:
    var isDown = false;
    
    $("#element").mousedown(function(){
        isDown = true;
    });
    
    $(document).mouseup(function(){
        if(isDown){
            //do something
            isDown = false;
        }
    }); 
    

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

    【讨论】:

    • 重要 这在选择文本时不起作用(至少在 Chrome 中,因为它将被视为拖动事件)。请参阅下面的解决方法
    【解决方案2】:

    选择文本时,上述答案将不起作用。

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

    在您的 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');
        }
    })
    

    【讨论】:

    • 啊,谢谢。反正我不需要文本选择,所以我禁用了它。见memela.com。但如果有人需要,这是一个很好的答案。
    • 是的,但是如果用户移动到元素之外,他们最终可能会选择文本,这样下次 mouseUp 就不起作用了
    【解决方案3】:

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

      mike 和 waitingforatrain 的答案在 GWT 中的可能实现。 在 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();
      }
      

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

      【讨论】:

        【解决方案5】:

        如果你有很多像我一样的可点击元素,你会想要创建一个全局鼠标捕捉器并将你的 mouseup 代码设置在被点击元素的 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.
                }
            });
        

        【讨论】:

          猜你喜欢
          • 2023-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-25
          • 2022-10-13
          • 2016-07-10
          相关资源
          最近更新 更多