jQuery bind click * что-нибудь* но * элемент*


скажем, есть некоторые элементы, плавающие вокруг, и я пытаюсь сделать некоторые, когда я нажимаю что-нибудь(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
});
5 57

5 ответов:

чтобы справиться с "сделать это за исключением, когда этой элемент нажат " ситуация, общий подход заключается в добавлении обработчика событий в document который обрабатывает случай "do this", а затем добавляет другой обработчик событий в элемент" except this", который просто предотвращает появление события click до 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.
});

посмотреть the event.stopPropagation() документация. Для тех из вас, кто использует версии ранее, чем jQuery 1.7 (как было в случае, когда этот вопрос был задан), вы не сможете использовать on(); вместо простого заменить 2 использования on() С bind(); подпись в данном случае та же.

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

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

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

Я делал это так в прошлом:

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

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

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

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

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