views:

572

answers:

1

I have elements that are under an element with opacity:0.5 that I want to be able to click on. How can I click "through" the topmost element?

Here's an example that demonstrates my problem. Click on the boxes to toggle them on and off. You can edit it on jsbin to try out your solution.

Bonus points if you can have the boxes toggle on hover.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt; 
<title>Sandbox</title> 
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
<style type="text/css" media="screen"> 
body { background-color: #000; } 
.box {width: 50px; height: 50px; border: 1px solid white} 
.highlight {background-color: yellow;} 
</style>
<script type="text/javascript">
var dthen = new Date();
$('<div id="past">').css({'height':  (dthen.getMinutes()*60)+dthen.getSeconds() +'px'
      ,'position': 'absolute'
      ,'width': '200px'
      ,'top': '0px'
      ,'background-color': 'grey'
      ,'opacity': '0.5'
      })
     .appendTo("#container");

setInterval(function(){
    dNow = new Date();
    $('#past').css('height', ((dNow.getSeconds()+(dNow.getMilliseconds()/1000))*50)%300 +'px');
},10)

 $(".box").click(function(){
      $(this).toggleClass("highlight");
    });
</script>
</head> 
<body> 
  <div id="container"> 
     <div class="box" style="position:absolute; top: 25px; left: 25px;"></div> 
     <div class="box" style="position:absolute; top: 50px; left: 125px;"></div> 
     <div class="box" style="position:absolute; top: 100px; left: 25px;"></div> 
     <div class="box" style="position:absolute; top: 125px; left: 125px;"></div> 
     <div class="box" style="position:absolute; top: 225px; left: 25px;"></div> 
     <div class="box" style="position:absolute; top: 185px; left: 125px;"></div> 
  </div> 
</body> 
</html>
+9  A: 

If you topmost element is contained within the element below, you can let the event "bubble through". If it is not, you have to trigger the click manually. There is no way to fire the event handler just by clicking.

To fire the event manually, you could do this:

$("#topelement").click(function() {
   $("#elementbelow").click();
   return false;
});

EDIT (response to comments):

To enumerate all boxes, you can do this (off the top of my head. no testing, could not even be syntax-error free)

$("#topelement").click(function(e) {
    $(".box").each(function() {
       // check if clicked point (taken from event) is inside element
       var mouseX = e.pageX;
       var mouseY = e.pageY;
       var offset = $(this).offset;
       var width = $(this).width();
       var height = $(this).height();

       if (mouseX > offset.left && mouseX < offset.left+width 
           && mouseY > offset.top && mouseY < offset.top+height)
         $(this).click(); // force click event
    });
});
Philippe Leybaert
substituting #topelement -> #past, #elementbelow -> #container didn't work.
Sam Hasler
Note there are several elements below the topmost element, I want to know which was clicked on.
Sam Hasler
You would have to enumerate all DOM elements to see if the clicked point is inside one or more elements. There is no way the browser can do this for you
Philippe Leybaert
I didn't expect the browser to do this for me. I'm asking how to enumerate those DOM elements.
Sam Hasler
Thanks that worked a treat: http://jsbin.com/onamo/edit
Sam Hasler