web-dev-qa-db-ja.com

jQueryは、要素内でマウスダウンを検出し、次に要素外でマウスアップを検出します

描画キャンバスに似たものがあり、元に戻す目的でマウスアップでその状態をキャプチャします。キャンバスは全画面表示ではないため、ブラシで描画してキャンバスの外側に放すことができます。このようなもの:

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

しかし、これはもちろん機能しません。プレーンな$(document).mouseupも機能しません。これは、他にも多くのUI要素があり、UI要素をクリックするたびに状態が保存されるためです。

何か案は?

17
methodofaction
var isDown = false;

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

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

簡単にするために、グローバル名前空間にisDownを入れました。本番環境では、おそらくその変数のスコープを分離する必要があります。

34
mike

上記の回答は、テキストが選択されている場合は機能しません。

修正は、マウスが下がっているときにテキストが選択されないようにし、元に戻ったときにテキストを再度有効にすることです。

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');
    }
})
7
bcoughlan

この小さな解決策がお役に立てば幸いです。ここで実際の動作を確認できます: 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 :(');  
        }
    });
});
2
Nick G

GWTでのマイクとwaitingforatrainの回答の実装の可能性。 HTMLヘッドで、マウスアップイベント(javascriptコード)を管理します。

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

カスタムウィジェットクラスに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 () {
        [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();
}

最後の行は、画像のドラッグを防ぐのに役立ちます。実際、ユーザーが選択します。どれも十分ではありません。

0
makeroo

私のようにクリック可能な要素がたくさんある場合は、グローバルマウスキャッチャーを作成し、クリックした要素のマウスダウン内にマウスアップコードを設定する必要があります。これが私が使用したコードです。

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