web-dev-qa-db-ja.com

jQueryバインドクリック*何でも*要素*要素*

いくつかの要素が浮かんでいるとしましょう。指定した要素(div#specialなど)以外のANYTHING(divs、body、anything ...)をクリックすると、いくつかの要素を実行しようとしています。

私が考えることができる次の方法以外にこれを達成するためのより良い方法があるかどうか疑問に思っています...

$(document).bind('click', function(e) {
    get mouse position x, y
    get the element (div#special in this case) position x, y
    get the element width and height
    determine if the mouse is inside the element
    if(inside)
        do nothing
    else
        do something
});
66
railOne

「これを行うexcept whenthis要素がクリックされた」状況を処理するには、一般的なアプローチ「do this」ケースを処理するイベントハンドラをdocumentに追加し、「except this」要素に別のイベントハンドラを追加します。これにより、クリックイベントがdocument;

_$('#special').on('click', function(e) {
    e.stopPropagation();
});

$(document).on('click', function (e) {
 // Do whatever you want; the event that'd fire if the "special" element has been clicked on has been cancelled.
});
_

event.stopPropagation() documentation を参照してください。 jQuery 1.7より前のバージョンを使用している場合(この質問が尋ねられたときのように)、on();を使用することはできません。代わりに、 on() の2つの使用を bind() に置き換えるだけです。この場合の署名は同じです。

デモはこちら。 http://jsfiddle.net/HBbVC/

113
Matt

あなたもできる

$(document).bind('click', function(e) {
  if(!$(e.target).is('#special')) {
    // do something
  }
});

またはdiv#specialに実行可能な子要素がある場合

$(document).bind('click', function(e) {
  if($(e.target).closest('#special').length === 0) {
    // do something
  }
});
43
bmavity

私は過去にこのようにしました:

jQuery("body").bind("click", function(e)
{
    var obj = (e.target ? e.target : e.srcElement);
    if (obj.tagName != 'div' && obj.id != 'special')
    {
        // Perform your click action. 
        return false;
    }
});

これは、div#specialをクリックしなかった場合にのみ実行されます。正直、もっと良い方法があるかもしれませんが、これは私にとってはうまくいきました。

5
Dan Smith

別のバインドを行う必要があります。1回の機能でこのすべてのクリックを処理する必要はありません。

$('body').bind('click', function(e){
  bodyClickEvent();
});
$('div.floating').bind('click',function(e){
  elementClickEvent(this);
  e.stopPropagation(); //prevents bodyClickEvent
});
  $('div#special').bind('click', function(){
  e.stopPropagation(); //prevents bodyClickEvent
});
1
El'

クリックイベントを常にドキュメントにバインドするのが嫌いなので、私が抱えていた問題についてこれを書いたので、私のシナリオでは、関数からのコールバックを使用してこれが機能します。

$('#button').click(function(){
        //when the notification icon is clicked open the menu
        $('#menu').slideToggle('slow', function(){
            //then bind the close event to html so it closes when you mouse off it.
            $('html').bind('click', function(e){
                $('#menu').slideToggle('slow', function(){
                    //once html has been clicked and the menu has closed, unbind the html click so nothing else has to lag up
                    $('html').unbind('click');
                });
            });
            $('#menu').bind('click', function(e){
                //as when we click inside the menu it bubbles up and closes the menu when it hits html we have to stop the propagation while its open
                e.stopPropagation();
                //once propagation has been successful! and not letting the menu open/close we can unbind this as we dont need it!
                $('#menu').unbind('click');
            });
        });
    });
1
Owen