Документ не нажимает на элементы jQuery
Используя jQuery, как можно обнаруживать клики не на определенных элементах и выполнять действие, следовательно?
У меня есть следующий JavaScript
$('#master').click(function() {
$('#slave').toggle();
});
$(document).not('#master','#slave').click(function() {
$('#slave').hide();
});
и я не вижу, где я ошибаюсь логически. Вы можете увидеть живой пример здесь
Ответы
Ответ 1
Поскольку вы привязываетесь к событию click
в документе, вы можете использовать event.target, чтобы получить элемент, инициировавший событие:
$(document).click(function(event) {
if (!$(event.target).is("#master, #slave")) {
$("#slave").hide();
}
});
РЕДАКТИРОВАТЬ: Как справедливо указывает Маттиас в своем комментарии, приведенный выше код не сможет идентифицировать события щелчка, исходящие от потомков #master
и #slave
(если они есть). В этой ситуации вы можете использовать ближайший(), чтобы проверить цель события:
$(document).click(function(event) {
if (!$(event.target).closest("#master, #slave").length) {
$("#slave").hide();
}
});
Ответ 2
Делает ли этот код то, что вы хотите? (не совсем уверен, правильно ли я понял)
$('body').on('click', '*:not( #master, #slave )', function() {
$('#slave').hide();
});
http://jsfiddle.net/gZ4Hz/8/
Ответ 3
Событие делегирование уже давно поддерживается jQuery. Трудность заключается в создании соответствующего селектора. Первоначально использовался delegate
, но совсем недавно делегатская форма on
.
Цель делегирования событий - прослушивать события на дочерних элементах и вызывать обработчики связанных событий на этих элементах, как если бы они были привязаны к дочернему элементу, а не родительскому. Это означает, что вместо привязки обработчиков к каждому элементу в DOM вы привязываете обработчик к каждому элементу начального выбора (document
- это один элемент). Это также упрощает использование одного селектора для привязки к постоянно меняющемуся набору элементов, поскольку новые элементы будут распространять свои события на document
независимо от того, существовали они или нет, когда связался обработчик начального события:
$(document).on('click', '*:not(#master, #master *, #slave, #slave *)', function (e) {
//this will reference the clicked element
});
Кроме того, обратите внимание, что я не только сказал, что элементы не должны быть #master
или #slave
, они не должны быть дочерними элементами #master
или #slave
.
Ответ 4
Другая мысль, возможно, не работает, потому что ваш браузер не может отображать body
на высоте 100%; Попробуйте настроить базовый CSS, чтобы исправить высоту тела, а затем пару других мыслей.
e.stopPropagation(): предотвращает появление пузыря в дереве DOM, предотвращая уведомление получателей родительских событий.
Итак, если вы измените первый код клика на следующее:
$('#master').click(function(e) {
e.stopPropagation();
$('#slave').toggle();
});
Затем вы также можете изменить знак вызова второго:
$("body, body *").not('#master, #slave').click(function(e) {
$('#slave').hide();
});
И это должно покрыть его. Попробуй! или см. this jsFiddle
Ответ 5
Fredrik отвечает на работы для элементов, уже присутствующих в документе, но он не работает для элементов, вызванных вызовами ajax.
Я попробовал следующее, и это работает для меня. Совместное использование кода для будущих аякс-кодеров.
$(document).on('click',function(event) {
if (!$(event.target).closest("#selector").length) {
if ($('#selector').is(":visible"))
$('#selector').slideUp();
}
});
Опубликовал бы это как комментарий, но у меня недостаточно репутации.