How to disable / re-enable all click / touch / mouse events in an html element and child elements

I have a parent HTML element with various links, SVG, text inside it at different levels. When a specific link in the parent element is clicked, I try to fade it by 50% and disconnect any further interaction with it from touch / mouse events until it is turned back on.

My code is complex and spaghetti-like, so here is a very simple example:

$(function() { $('.container a').on({ // I'm just showing click below for simplicity, I'll be adding some handling for mouse/touch events. click: function(e) { $('.container').fadeTo("slow", 0.5); $('.info').fadeTo("slow", 1); } }); $('.info a').on({ click: function(e) { $('.info').fadeOut(); $('.container').fadeTo("slow", 1); } }); }); 
 .container { background-color: #123435; padding: 1em; } .info { display: none; background-color: #435123; padding: 1em; } .container a, .info, .info a { color: #bbc; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"> <a href="#">Show Info (click me)</a> <br> <a href="thingy1.htm">Other Link 1</a> </div> <div class="info"> Some info (div.container and all it contents now need to be totally disabled) <br> <a href="#">Hide Info</a> <br> </div> 

What i tried

When container turns pale, I tried setting disabled attributes for all children, which works for any form input, but not for links.

I also tried adding a “faded” class, and then testing it like this:

 $('.container:not(.faded) a').on({ click: function(e) { $('.container').addClass("faded").fadeTo("slow", 0.5); $('.info').fadeTo("slow", 1); } }); 

.. but it seems that the 'on' action does not account for the new class for the selector .. or something!

Help me please. I am very happy to consider a completely different way to handle this. Thanks.

+6
source share
5 answers

If you want to really disable everything, not just event handlers added using javascript, you must make sure that even all actions are not allowed by default.

An easy way to make sure that everything with an element is disabled is to place another element on top of it or using CSS to disable all pointer events

In modern browsers (from IE 11 and above) you can use event pointers

 $(function() { $('.container a').on('click', function(e) { $('.container').fadeTo("slow", 0.5).css('pointer-events', 'none'); $('.info').fadeTo("slow", 1); }); $('.info a').on('click', function(e) { $('.info').fadeOut(); $('.container').fadeTo("slow", 1).css('pointer-events', 'auto'); }); }); 
 .container { background-color: #123435; padding: 1em; } .info { display: none; background-color: #435123; padding: 1em; } .container a, .info, .info a { color: #bbc; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"> <a href="#">Show Info (click me)</a> <br> <a href="thingy1.htm">Other Link 1</a> </div> <div class="info">Some info (div.container and all it contents now need to be totally disabled) <br> <a href="#">Hide Info</a> <br> </div> 

In older browsers (IE 10 and below), you probably have to use an overlay that covers all other elements

 $('.container a').on('click', function(e) { $('.info').fadeTo("slow", 1); var container = $('.container').fadeTo("slow", 0.5); var overlay = container.clone(false); overlay.empty().prop('id', 'overlay').css({ cssText : container.css('cssText'), top : container.position().left, left : container.position().top, position : 'absolute', background : 'transparent' }).appendTo(container.parent()); }); $('.info a').on('click', function(e) { $('.info').fadeOut(); $('.container').fadeTo("slow", 1); $('#overlay').remove(); }); 
 .container { background-color: #123435; padding: 1em; } .info { display: none; background-color: #435123; padding: 1em; } .container a, .info, .info a { color: #bbc; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"> <a href="#">Show Info (click me)</a> <br> <a href="thingy1.htm">Other Link 1</a> </div> <div class="info">Some info (div.container and all it contents now need to be totally disabled) <br> <a href="#">Hide Info</a> <br> </div> 
+5
source

Flags are your best friends:

 var ClicksEnabled=true; $('.container a').on({ click: function (e) { if(ClicksEnabled){ $('.container').fadeTo("slow", 0.5); $('.info').fadeTo("slow", 1); ClicksEnabled=false; } } }); $('.container').on("click", "*", function (e) { if (!ClicksEnabled) { e.preventDefault(); } }); 

Here is your fixed snippet:

 $(function() { var ClicksEnabled = true; $('.container a.show_info').on({ click: function(e) { if (ClicksEnabled) { $('.container').fadeTo("slow", 0.5); $('.info').fadeTo("slow", 1); ClicksEnabled = false; } } }); $('.container').on("click", "*", function(e) { if (!ClicksEnabled) { e.preventDefault(); } }); $('.info a').on({ click: function(e) { if (!ClicksEnabled) { $('.info').fadeOut(); $('.container').fadeTo("slow", 1); ClicksEnabled = true; } } }); }); 
 .container { background-color: #123435; padding: 1em; } .info { display: none; background-color: #435123; padding: 1em; } .container a, .info, .info a { color: #bbc; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"> <a class="show_info" href="#">Show Info (click me)</a> <br/> <a href="thingy1.htm">Other Link 1</a> </div> <div class="info">Some info (div.container and all it contents now need to be totally disabled) <br/> <a href="#">Hide Info</a> <br/> </div> 
+3
source

You can use flags (read @Banana answer). In addition, you can (un) handle events with jQuery:

 // idea $('#selector').on('event.name', function(){ // do something // then remove event $(this).off('.name'); }); // example $('#selector').on('click.eventsGroup1', function(){ // do something // then remove event $(this).off('.eventsGroup1'); }); 

You have all the information you need in jQuery Docs .

+3
source

using css you can specify whether an element can receive mouse events:

https://developer.mozilla.org/en/docs/Web/CSS/pointer-events

To disable mouse events:

 $(".container a").css({ "pointer-events": "none" }); 

turning them on again:

 $(".container a").css({ "pointer-events": "auto" }); 
+2
source

As many posters note, you can use the pointer-events property to prevent clicks. Since inline styles are evil, I will post a CSS solution: add a class to the element and disable it:

 .disable-click { pointer-events: none; position: relative; } .disable-click * { pointer-events: none; } .disable-click:before { content: ""; pointer-events: none; position: absolute; top: 0; bottom:0; left:0; right:0; background: transparent; } 

This should prevent users from interacting with the container, and children with click and touch events. This works best in modern browsers, but I also added a pseudo-element “mask” that will provide similar functionality for older browsers.

Please note: this will not always prevent users from entering the tab into the “disabled” item using the keyboard. This is especially true for older browsers.

+1
source

Source: https://habr.com/ru/post/988569/


All Articles