views:

1107

answers:

8

I'm trying to overlay a element on top of a webpage (to draw arbitrary graphics), and I've come to the point where I can stack it inside of a element on top of everything, but this prevents the user from clicking on any links/buttons/etc. Is there a way to have its content float on top of everything (it's semi-transparent, so you can still see what is behind) and have the user interact with the layer below it?

I've found a lot of information on the DOM event model, but none of it addresses the problem where the buttons and other "native" controls never seem to get the clicks in the first place.

Thanks for any help!

+3  A: 

Hi,

You can use an overlay with opacity set in order to the buttons/anchors in the back stay visible, but once you have that overlay over an element, you can't click it.

yoda
I think that if the overlay is transparent (as in no background, a transparent image as background will not work), clicks will fall through. I'm not sure if this works for all browsers though.
GoodEnough
Correct, as this is how clickjacking occurs (transparent fullscreen iframe sits on top of a page).
cballou
A: 

This is a horrible idea, this is very similar to "Click-Jacking" used by very unsavory characters. Good security tools(i.e. NoScripts) will id this as a possible hostile site and ask the user to direct away from the site.

WolfmanDragon
Sounds like the opposite to me. I think he wants the clicks to pass through the transparent layer, without taking any action, allowing the user direct access to the layer beneath.
Bill the Lizard
This isn't click-jacking, its sort of the opposite. And besides, as long as there are no iframes or cross-domain things going on here, I don't see the problem. I doubt security tools would notice it.
Russell Leggett
This is strictly going to be in the control of the user - I'm not trying to do anything shady! I want to allow the user to "draw" over a webpage. It'll probably end up as a Greasemonkey thing.
Steven Schlansker
A: 

Generally, this isn't a great idea. Taking your scenario, if you had evil intentions, you could hide everything underneath your "overlay". Then, when a user clicks on a link they think should take them to bankofamerica.com, instead it triggers the hidden link which takes them to myevilsite.com.

That said, event bubbling works, and if it's within an application, it's not a big deal. The following code is an example. Clicking the blue area pops up an alert, even though the alert is set on the red area. Note that the orange area does NOT work, because the event will propagate through the PARENT elements, so your overlay needs to be inside whatever element you're observing the clicks on. In your scenario, you may be out of luck.

<html>
<head>
</head>
<body>
    <div id="outer" style="position:absolute;height:50px;width:60px;z-index:1;background-color:red;top:5px;left:5px;" onclick="alert('outer')"> 
     <div id="nested" style="position:absolute;height:50px;width:60px;z-index:2;background-color:blue;top:15px;left:15px;">
     </div>
    </div>
    <div id="separate" style="position:absolute;height:50px;width:60px;z-index:3;background-color:orange;top:25px;left:25px;">
    </div>
</body>
</html>
jvenema
"Taking your scenario, if you had evil intentions, you could hide everything underneath your "overlay". Then, when a user clicks on a link they think should take them to bankofamerica.com, instead it triggers the hidden link which takes them to myevilsite.com." -- That doesn't even make sense. Why would he need to go to the trouble. He could just use js to go there, why would he need to trigger a hidden link?
Russell Leggett
No evil intentions here! This is strictly in-house; it only really has to work on one of Safari or Firefox on exactly one computer :)I care nothing about portability at the moment.Your idea is interesting, but it requires nesting within the element - which does not work for things like form buttons or links, which is the use case I described in the original post :(
Steven Schlansker
@Steven, I know, which is why I mentioned that I think you're out of luck on that approach.@Russell, if you consider then that you can have a user perform actions without them knowing it, you can do things like start redirecting keyboard events, etc, which, in turn, would let you enter filenames for upload, and so on. This was a big deal with flash not too long ago, because without knowing it, you could turn on your flash webcam and/or audio controls and send audio/video without realizing it.
jvenema
+5  A: 

My suggestion would be that you could capture the click event with the overlay, hide the overlay, then refire the click event, then display the overlay again. I'm not sure if you'd get a flicker effect though.

[Update] Exactly this problem and exactly my solution just appeared in this post: "Forwarding Mouse Events Through Layers". I know its probably a little late for the OP, but for the sake of somebody having this problem in the future, I though I would include it.

Russell Leggett
The link you provided is awesome. In particular, it allowed me to learn about Mozilla "pointer-events" property that does exactly the trick. http://hacks.mozilla.org/2009/12/pointer-events-for-html-in-firefox-3-6/
NicDumZ
A: 

In case anyone else is running in to the same problem, the only solution I could find that satisfied me was to have the canvas cover everything and then to raise the Z-index of all clickable elements. You can't draw on them, but at least they are clickable...

Steven Schlansker
A: 

@crossbrowser: (why can't I comment? do I not have enough karma?) Links will not fall through even if the alpha and opacity are 0.

Here is the proof: http://dl.getdropbox.com/u/234659/overlay%5Ftest.html .

rabidsnail
A: 

Sorry, probably too late to be much use, but for the record an alternative solution might be to make the clickable layer the overlay: you make it semi-transparent and then place the "overlay" image behind it (somewhat counterintuitively, the "overlay" image could then be opaque). Depending on what you're trying to do, you might well be able to get the exact same visual effect (of an image and a clickable layer semi-transparently superimposed on top of each other), while avoiding clickability problems (because the "overlay" is in fact in the background).

Nick F
A: 

I asked a similar question, and Ionuț G. Stan gave this answer:

It can be done using CSS pointer-events in Firefox >= 3.6 and Safari >= 4.0. Probably some Chrome version too. Unfortunately, I don't have knowledge of a cross-browser workaround.

#overlay {
  pointer-events: none;
}
David Wolever
Thanks for the response - unfortunately I've long since moved on so won't be testing it... :-)
Steven Schlansker