jQuery: перехватывать все события кликов до того, как они произойдут?

На моей странице много различных элементов, которые реагируют на клики. Бывают случаи, когда мне нужно заблокировать все клики на основе какого-то глобального флага. Есть ли способ сделать эту проверку централизованно?

Прямо сейчас в каждом событии я проверяю наличие флага, например:

var canClick = false; // Global flag

// Sample click event:
$("#someDiv").click(function(){
  if(!canClick) return;

  // Some stuff ...
});

Что я хотел бы сделать, так это иметь один элемент, который перехватывает все события щелчка до любых других элементов.

Я попытался сделать это с document, но эти события происходят только после других событий щелчка.

Пример:

$("#someDiv").click(function(){ console.log("someDiv click"); });

$(document).click(function(){ console.log("Document click"); });

// When I click on the someDiv element it prints:
> someDiv click
> Document click

Я также попытался поместить полноэкранный div поверх всего и использовать его для захвата событий, но проблема заключалась в том, что ни один из кликов не распространялся через этот полноэкранный div. Также я не хочу полагаться на создание дополнительных элементов для захвата кликов, так как это кажется немного хакерским.

Могу ли я перезаписать функцию щелчка jQuery, чтобы я мог поставить туда свой маленький чек?

Есть ли что-то очевидное, что мне здесь не хватает?

Спасибо за любую помощь.


person nebs    schedule 27.05.2011    source источник


Ответы (3)


Да, используйте .addEventListener() и установите для третьего параметра значение true. Это привяжет прослушиватель к фазе захвата и выполнит функцию до того, как будет выполнено что-либо еще.

Вот пример, когда это остановит выполнение всех обработчиков кликов:

document.addEventListener('click', function(e) {
    e.stopPropagation();
}, true);

Посмотрите это в действии здесь:

http://jsfiddle.net/wLwMh/1/

person John Strickler    schedule 27.05.2011
comment
Ааа гениально! Большое спасибо, добрый господин. Работает в Chrome 11, это единственный браузер, с которым мне нужна совместимость. Ваше здоровье. - person nebs; 28.05.2011
comment
Для тех, кому нужна кросс-браузерная совместимость, это не поддерживается IE‹9. - person opsb; 05.03.2013
comment
Как это сделать с элементом? - person Sumesh TG; 18.09.2018

Вы можете захватить все события кликов, а затем вызвать пользовательское событие, в котором ваши слушатели будут привязаны после проверки.

$("#someDiv").bind('awesomeEvent', function() {
    //do stuff here
}

$(*).click(function() {
    if(canClick) {
        $(this).trigger('awesomeEvent');
    }
}

РЕДАКТИРОВАТЬ Я должен упомянуть, что использование селектора $(*) не является хорошей идеей с точки зрения производительности. Вы действительно должны попытаться как-то сузить рамки.

person Dave    schedule 27.05.2011

Использование инжекта Javascript:

view.loadUrl(
                    "javascript:(function() {"


                            + "document.addEventListener('click', function(e)"
                            + "{"
                            + "e.stopPropagation();"
                            + "}"
                            + ", true);"

                            + "})()"
            );
person Brian G9    schedule 19.01.2020
comment
Это не дает ответа на вопрос. Пожалуйста, отредактируйте свой ответ, чтобы убедиться, что он улучшает другие ответы, уже присутствующие в этом вопросе. - person hongsy; 19.01.2020
comment
Пожалуйста, рассмотрите возможность добавления некоторых пояснений или деталей к вашему ответу. Хотя это может ответить на вопрос, просто добавление фрагмента кода в качестве ответа, по сути, не помогает ОП или будущим членам сообщества понять проблему или предлагаемое решение. - person Maxim; 19.01.2020