jQuery связать нажмите * НИЧЕГО *, но * ЭЛЕМЕНТ * - PullRequest
66 голосов
/ 09 июля 2011

Скажем, есть некоторые элементы, плавающие вокруг, и я пытаюсь сделать некоторые, когда я нажимаю НИЧЕГО (divs, body, что угодно ...), кроме указанного (например, 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
});

Ответы [ 5 ]

112 голосов
/ 09 июля 2011

Для обработки ситуации «сделать это за исключением , когда этот элемент нажат», общий подход заключается в добавлении обработчика событий в document который обрабатывает случай «сделать это», затем добавляет еще один обработчик событий к элементу «кроме этого», который просто предотвращает всплывающее событие клика до 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/

43 голосов
/ 27 февраля 2013

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

$(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
  }
});
5 голосов
/ 09 июля 2011

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

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

1 голос
/ 16 октября 2012

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

$('#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 голос
/ 09 июля 2011

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

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