У меня есть .main
которые содержат список динамического контента, который можно добавить "на лету". .main
также можно отключить с .disable
класса .disable
. Когда он отключен, я не хочу, чтобы все элементы контента были нажаты.
Ниже вы можете видеть, что я использую взломать для обнаружения .disable
класса после .main
. Есть ли способ структурировать селектор CSS для jQuery, чтобы избежать сбора дочерних событий DOM, если у родителя есть определенный класс? Может быть, какой-то .main:not(.disable)
но я не мог понять, как это сделать.
Код: http://jsfiddle.net/qhoc/99rjU/
HTML:
<div class="main">
<div class="state">Enabled</div>
<ul>
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
</ul>
</div>
<a class="btn" href="#">
Toggle State
</a>
Javascript:
$('.btn').on('click', function() {
if ($('.main').hasClass('disable')) {
$('.main').toggleClass('disable');
$('.state').text('Enabled');
} else {
$('.main').toggleClass('disable');
$('.state').text('Disabled');
}
});
$('.main').on('click', ' ul li', function() {
/* This is a hack
if ($('.main').hasClass('disable'))
return;
*/
alert('Item is clicked');
});
Я думал о других нечистых альтернативах:
Делайте все клики по всему body
такие как $('body').on('click', '.main:not(.disable) ul li', function()
но этот очень уродливый! Он должен сканировать весь объект на каждом клике
Unbind li
click event каждый раз, когда a
является триггером для disable
вызова. Но является ли это оптимальной или лучшей практикой?
ОБНОВЛЕНИЕ 1:
Так что фактически в моем проекте я хочу только отключить a
в списке. Поскольку есть другие buttons
и divs
которые я все еще хочу вызвать событие. Однако, похоже, что использование этого не будет работать
.disable li a
{
pointer-events: none;
}
Вот ссылка на это http://jsfiddle.net/qhoc/99rjU/2/
Похоже, что это все еще экспериментально и не будет работать на теге привязки??
https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
Ну, вы можете отключить все события click на div, когда у него есть класс .disable
css:
.disable
{
pointer-events: none;
}
Таким образом, ничто внутри div не является интерактивным.
Для IE это как-то сложнее, так как IE 10 и ниже не поддерживают pointer-events
. Однако была написана замечательная статья о том, как обойти это с помощью функции слоя: http://www.vinylfox.com/forwarding-mouse-events-through-layers/
Надеюсь, это то, что вы имеете в виду.
pointer-events: none;
не похож на работу с a
тегом !!?
<li>
. Вы можете отключить это, если хотите. Вы также можете изменить свой код jQuery, чтобы он срабатывал только при нажатии <a>
. Скажи мне, если ты этого хочешь, и я покажу пример. pointer-events: none;
работает с якорями.
$('.btn').on('click', function() {
var main = $('.main');
$('.state').text(main.hasClass('disable') ? 'Enabled' : 'Disabled');
main.toggleClass('disable');
});
$('.main').on('click', 'li', function(e) {
if ($(this).parents('.main.disable').length) {
// actually this is similar to your alternative#1
return;
}
alert('Item is clicked');
});
Как насчет этого?
body
и, если щелчок происходит, он просматривает цепочку элементов, через которые прошел клик (что, вероятно, всего лишь от трех до 10?), Начиная сe.target
и продолжая до каждогоparentNode
до достигаетbody
. Это происходит в микросекундах.