jQuery: Trap all click events before they happen?

2019-01-24 01:46发布

问题:

On my page I have a lot of various elements which respond to click events. There are times when I need to block all clicks based on some global flag. Is there a way I can make this check in a centralized location?

Right now in each event I check for the flag, for example:

var canClick = false; // Global flag

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

  // Some stuff ...
});

What I'd like to do is have one element which traps all click events before any other elements.

I tried doing it on document but these events only occur after the other click events.

Example:

$("#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

I also tried putting a full screen div on top of everything and using this to trap events but the problem there was that none of the clicks were being propagated through this full screen div. Also I don't want to rely on creating extra elements to trap clicks as it feels a little hacky.

Could I maybe overwrite the jQuery click function so that I can put my little check in there?

Is there something obvious I'm missing here?

Thanks for any help.

回答1:

Yes, use .addEventListener() and set the 3rd option to true. This will bind the listener to the capture phase and execute the function before anything else gets executed.

Here's an example where this will stop all click handlers from executing:

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

See it in action here:

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



回答2:

You could capture all the click events then trigger a custom event where you have your listeners bound after your check

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

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

EDIT I should mention that using the $(*) selector is not a good idea from a performance standpoint. You should really try and narrow the scope somehow.