3

I need to disable any activity on a web page before a flag is set. Let's ignore the flag and say I just want to disable any clicking on the page forever. I thought it would be as simple as:

$(window).click(function(e) {
    e.preventDefault();
});

Given the above, I can still, however, click links just fine.

How can I render all clicking inert?

j08691
  • 204,283
  • 31
  • 260
  • 272
FOO
  • 612
  • 5
  • 16

6 Answers6

13

You can't proceed like this because the click is first catched by the link before it is forwarded to the enclosing elements.

The simplest solution would be to put an invisible div over the window :

#mask {
    position: fixed;
    left:0; right:0; top:0; bottom:0;
}

As pointed by Connor, you might need to set a z-index (in fact it depends on the rest of the page).

Demonstration

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 4
    **+1** `z-index` might also be needed – iConnor Oct 10 '13 at 17:17
  • This is probably the best solution. Food for thought though: a savvy user can still open their web inspector and remove the overlay element thus allowing them to interact with the page. – rescuecreative Oct 10 '13 at 17:20
  • 1
    The likelyhood of them being able to do that before the dom is ready is slim though, unless your dom ready event takes a while of course. in my case they'd only have 600ms or less to open the console and do that. Even then, if they use the console, they can remove all click handlers anyway even after dom ready. – Kevin B Oct 10 '13 at 17:21
  • @rescuecreative and you can also do `$(element).trigger('click');` so that really doesn't matter. – iConnor Oct 10 '13 at 17:22
  • Any `ad blocker` can quickly be set to delete `#mask` when page loads by users who aren't technically minded. – Reactgular Oct 10 '13 at 17:28
  • 1
    `..` and then `$("a").each(function(){$(this).attr("href",$(this).data("src"));});` – Reactgular Oct 10 '13 at 17:36
  • @dave If you want to handle the case of users not having javascript, then just set the mask using ``. – Denys Séguret Oct 10 '13 at 17:39
  • 1
    @dystroy - That would require the body to already be rendering which might (unlikely) allow some click events to be vulnerable. Perhaps ``. – Travis J Oct 10 '13 at 17:41
4

Besides dystroy answer other thing you can do is set a class no-click to your body and the following css

body.no-click * {
    pointer-events: none;
}

To enable clicks, just remove the class no-click from your body

If you need support < IE 11, forgot about pointer-events. Compatibility

DEMO

Oswaldo Acauan
  • 2,730
  • 15
  • 23
  • 1
    This works for me, but [caniuse](http://caniuse.com/#feat=pointer-events) says that it is not supported in ie10-. – Travis J Oct 10 '13 at 17:43
2

This is what I'd do:

var done = false;
$('body').on('click', '*', function(e) {
    if (!done) e.preventDefault();
}).on('load', function() {
    done = true;
});
Zathrus Writer
  • 4,311
  • 5
  • 27
  • 50
0

If you'd need to completely stop clicks on the page, you could unbind all click events, like in this answer:

https://stackoverflow.com/a/13056681/303552

function RecursiveUnbind($jElement) {
    // remove this element's and all of its children's click events
    $jElement.unbind();
    $jElement.removeAttr('onclick');
    $jElement.children().each(function () {
        RecursiveUnbind($(this));
    });
}

You would call the function like this:

RecursiveUnbind($(window));
Community
  • 1
  • 1
jbkkd
  • 1,510
  • 5
  • 18
  • 37
-1

By just returning false

$("*").on("click",function(e) {
    e.preventDefault();
return false
});

or

$("*").on("click",function(e) {
    e.preventDefault();
e.stopPropagation()
});

Both of these stop the propagations to their parent elements and hence the default gets prevented

Akshay Khandelwal
  • 1,570
  • 11
  • 19
-1

I think this is what you're looking for. Using namespaces so you don't undo any other click events.

NOTE: The click that does the preventing must be above any other script tags.

Example: http://jsfiddle.net/qNuRA/2/

$('*').on('click.startup', function (e) {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
});

$(document).ready(function () {
    $('*').off('click.startup');
});
Dave
  • 2,506
  • 2
  • 20
  • 27
  • This doesn't work in the general case of a jQuery application : http://jsfiddle.net/UjCaG/ – Denys Séguret Oct 10 '13 at 17:33
  • (Left hand side of jsfiddle under frameworks and extensions, you had it not running the javascript UNTIL onload, that's all I changed. – Dave Oct 10 '13 at 17:36
  • I saw. But you're still handling only some specific cases. See http://jsfiddle.net/qNuRA/. I think that OP wants a general solution. BTW, I didn't downvote you, I don't think your answer should have been downvoted. – Denys Séguret Oct 10 '13 at 17:37
  • Didn't realize the issue you presented. Thanks for that. The OP originally asked how does he apply this to a links as well, and my solution addresses this – Dave Oct 10 '13 at 17:53
  • @dystroy, I think this issue you brought up is solved as long as you ensure that the script that prevents the button from being clicked is loaded before anything else. http://jsfiddle.net/qNuRA/1/ – Dave Oct 10 '13 at 18:50