Хотя вы, надеюсь, нашли свое собственное решение для этого за годы, прошедшие с момента его запроса, я добавляю соответствующий ответ, поскольку у меня была похожая проблема, которую нужно было решить.
По сути, есть дваразличные способы решения этой проблемы, которые соответствуют вашим критериям (которые тоже были моими!).Оба они являются гибкими для типов элементов (они работают не только с элементами).
(для обоих этих решений предположим, что класс working-links
применяется к любым элементам контейнера, которые вы хотитеиметь функциональные ссылки внутри. Имейте в виду, что, хотя оба эти примера основаны на использовании document
в качестве целевого контейнера для предотвращения работы ссылок, обычно более целесообразно, чтобы цель была чем-то более изысканным, напримернезависимо от того, что окружает основную область содержимого страницы)
Первое - это отключить все щелчковые действия по умолчанию в документе, а затем (по существу) повторно включить их в соответствующем контейнере.
На практике это работает так, что обработчик событий применяется к самому объекту документа (или к любому элементу, содержащему все, что необходимо предотвратить - что было бы лучше, чтобы меню сайта и т. Д. По-прежнему работали без изменений).События всплывают вверх: вам не нужен обработчик событий для каждой ссылки, вам нужен только один в документе, чтобы перехватывать любые щелчки по ссылкам.
Мы можем воспользоваться этим поведением, чтобы прикрепить другой обработчик событий к любомуконтейнеры, в которых мы хотим, чтобы клики работали (скажем, с классом working-links
), что предотвращает распространение события click до обработчика, прикрепленного к объекту документа.
$(document).on("click", function(event) {
event.preventDefault();
});
$(".working-links").on("click", function(event) {
event.stopPropagation();
});
Пример ссопровождающий HTML-код на codepen.io
Обратите внимание, что я предоставил их, используя on()
вместо click()
, поскольку он позволяет легко изменить их на делегированные события, если вы нацеливаетесь на что-то другое, кромевесь документ и может иметь больше целевых областей, вставляемых динамически (AJAX / и т. д.).Это имеет значение только в том случае, если вы решили связать событие более избирательно: на уровне документа любые изменения внутри него не имеют значения и будут по-прежнему фиксироваться привязкой события, поскольку они все равно будут всплывать должным образом.
Это может иметь большее значение для события working-links: вам потребуется , чтобы соответствующим образом изменить это, чтобы добавить селектор в on()
, если вы динамически добавляете больше на страницу после того, как этоbound.
Если вы попытались присоединить обработчик, а затем выборочно удалить его из соответствующим образом классифицированного элемента, или если вы пытались присоединить обработчик только к элементам, которые не имели класса (с помощью селектора CSS :not
илиограничивая выбор jquery с помощью .not()
), это поведение пузыри было причиной того, что оно не работало.Даже если вы не прикрепите event.preventDefault()
к ссылкам или их контейнерам, если он присоединится к любому из их предков, он будет пузыриться на них, и действие все равно будет предотвращено.
Другойметод состоит в том, чтобы применить обработчик события click к элементу document / main container, а затем применить логику, зависящую от event.target
.
. Это довольно просто, но, возможно, не так элегантно.
Мы собираемся просто захватить все события щелчка в документе (или в любом другом контейнере, который вы выбрали для таргетинга) и выяснить, заключен ли event.target в один из наших исключающих элементов.Самый простой способ сделать это, вероятно, использовать функцию is()
в jquery.
Следует иметь в виду, что вам нужно будет проверять не только, находится ли event.target
в наборе элементов, совпадающем сселектор класса, но также и все дочерние элементы селектора класса: в противном случае любые элементы , вложенные вне непосредственных дочерних элементов, не будут работать.
$(document).on("click", function(event) {
if (! $(event.target).is($(".working-links, .working-links *").children())) {
event.preventDefault();
}
});
Пример с сопровождающим HTML-кодом на codepen.io
С другой стороны, этот метод не требует каких-либо изменений для функционирования на динамической странице, по крайней мере, для добавления working-links
классифицированных элементов. Если вы добавляете больше контейнеров без щелчков, то, очевидно, его необходимо соответствующим образом адаптировать для использования режима делегирования вызовов on()
(см. Соответствующую документацию jQuery по привязке событий).
С другой стороны, это будет использовать немного больше ресурсов для обработчика событий (чтобы вычислять элемент jQuery, установленный при каждом запуске), чем другой метод. Нам, вероятно, наплевать в большинстве случаев, но это не так уж и плохо.