JQuery bind click * НИЧЕГО * но * ELEMENT *

Скажем, что вокруг есть некоторые элементы, и я пытаюсь сделать что-то, когда я нажимаю "НИЧЕГО" (divs, body, whatever...), но тот, который указан (например, div # special).

Мне интересно, есть ли лучший способ достичь этого, кроме следующего метода, о котором я могу думать...

$(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
});

Ответы

Ответ 1

Чтобы обрабатывать "делать это, если не было нажата кнопка этого элемента", общий подход состоит в том, чтобы добавить обработчик события в 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(). Для тех из вас, кто использует версии раньше, чем jQuery 1.7 (как и в случае, когда задавался этот вопрос), вы не сможете использовать on(); вместо этого просто замените 2 использования on() с bind(); подпись в этом случае одинакова.

Демо здесь; http://jsfiddle.net/HBbVC/

Ответ 2

Вы также можете сделать

$(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
  }
});

Ответ 3

В прошлом я делал это так:

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. Честно говоря, могут быть лучшие способы сделать это, но это сработало для меня.

Ответ 4

вам нужно выполнить разные привязки, нет необходимости обрабатывать все эти клики в одной функции

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

Ответ 5

Я написал это сегодня для проблемы, с которой я сталкивался, поскольку мне не нравится, когда события кликов привязаны к документу все время, поэтому для моего сценария это работает, используя обратные вызовы из функций.

$('#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');
            });
        });
    });