jquery: How to enable clicks in a zone of the page (disabling rest)
I would like to do a tutorial in a page, so my idea is to create some kind of "mask" that disable all the page and enable just a "invisible" box, where things (links and other stuff of the page) works.
It's like a "ozone hole" where links and stuff works, but if you click anywhere else on the page, the click is "captured" and do nothing.
jQuery(".tutorial_holes").click(function(){
xxxxx
});
jQuery(document).click( function() { return false; } });
I'm st开发者_如何学编程arting working with this ... but I do not know what to put in "xxxx" to tell it "leave this area working".
Also I tried with a 100% overlay with z-index:10000 , and above it (z-index:10001) create the "hole" ... but I do not either how to tell javascript to allow clicks in this area of the belowest original page ...
I hope I explained myself :)
Solutions like dialog or adding "disable" classes to elements will not work:
a) Dialog creates a box over the page in which you can "play" ... what I want is exactly the opposite, create a box IN THE PAGE where you can play, disabling the rest
b) Adding "#disable" or similar solutions to elements to disable them after is crazy. I have tons of other jquery plugins and behaviours. I'd need to modify a lot each page. What I need is a non-intrusive solution "over" all my code
Any ideas ?
Use event.preventDefault()
, here is an example
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head>
</head>
<body>
<div id="disabled">
<a href="http://www.example.com">foo</a>
<form action="http://www.example.com">
<input type="submit" value="" name="" />
</form>
</div>
<script type='text/javascript' src='http://code.jquery.com/jquery-latest.min.js'></script>
<script>
$(document).ready(function(){
$("#disabled a, #disabled input").click(function(event){
event.preventDefault();
});
});
</script>
</body></html>
You can use jQuery dialog plugin comes in jQueryUI which is the easiest and fastest way to achieve the feature which you need. Check it out.
http://jqueryui.com/demos/dialog/
While you've hopefully found your own solution to this in the years since it was asked, I'm throwing in an appropriate answer since I had a similar problem that needed solving.
There are essentially two different ways of solving this which meet your criteria (which happened to be mine as well!). Both of these are flexible to element types (they work on more than just <a> elements).
(for both of these solutions, assume that the class working-links
is being applied to any container elements you wish to have functional linking inside of. Keep in mind that while both of these examples are based off of using document
as the target container for preventing links from working, it would usually make more sense to have the target be something more refined, like whatever wraps the main content region of the page)
The first is to disable all default click actions on the document, and then (essentially) re-enable them on an appropriate container.
How this works in practice is that an event handler is applied to the document object itself (or any element containing everything that needs to be prevented—which would be best so that site menus/etc still work with no changes needed). Events bubble upwards: you don't need an event handler on every link, you just need one on the document to intercept any clicks on links.
We can take advantage of this behavior to attach another event handler on any containers we want clicks to work within (say, one with a class of working-links
) which prevents the click event from propagating up to the handler attached to the document object.
$(document).on("click", function(event) {
event.preventDefault();
});
$(".working-links").on("click", function(event) {
event.stopPropagation();
});
Example with accompanying HTML on codepen.io
Note that I've provided these using on()
instead of click()
because it allows for easily changing these to being delegated events if you are targeting something other than the entire document and may have more targeted regions inserted dynamically (AJAX/etc). This only matters if you chose to bind the event more selectively: at the document level, any changes inside it don't matter and will still be captured by the event binding, since they'll still bubble up properly.
This may matter more for the working-links event: you will need to change that appropriately to add a selector in on()
if you are dynamically adding more to the page after this is bound.
If you tried attaching a handler and then selectively removing it from an appropriately classed item, or if you tried attaching a handler only to elements that did not have a class (using the CSS selector :not
or by restricting the jquery selection using .not()
) this bubbling behavior is why it did not work. Even if you don't attach the event.preventDefault()
to the links or their container, if it attaches to any of their ancestors it will bubble to them and the action will still be prevented.
The other method is to apply a click event handler to the document/main container element, and then apply logic dependent on the event.target
.
This one is pretty straightforward, but possibly not as elegant.
We're going to simply capture all click events at the document (or whatever container you choose to target) and figure out if the event.target is wrapped within one of our excluding elements. The easiest way to do this is probably to use jquery's is()
function.
One thing to keep in mind is that you will need to check not only if the event.target
is within the element set matched by the class selector, but also all children of the class selector: otherwise any <a> elements nested beyond the immediate children will fail to work.
$(document).on("click", function(event) {
if (! $(event.target).is($(".working-links, .working-links *").children())) {
event.preventDefault();
}
});
Example with accompanying HTML on codepen.io
On the plus side, this method does not require any changes in order to function within a dynamic page, at least for the addition of working-links
classed elements. If you're adding more of the non-click containers, it will obviously need to be adapted appropriately to make the on()
call use delegation mode (see the appropriate jQuery documentation on event binding).
On the down side, this is going to use a bit more resources for the event handler (in order to calculate the jQuery element set each time it runs) than the other method. We probably don't care in most circumstances, but it's not a bad thing to be aware of.
精彩评论