views:

440

answers:

2

Here is the scenario:

You have two images and they are stacked on one another. The highest-order z-indexed image is responsible for handling click events (think Google's Map API) and is transparent, while the image below is responsible for a visual representation.

Here is a pseudo-HTML/CSS representation:

div.visual-container {
    width: 10px;
    height: 10px;
}

div.visual-container:hover {
    background-color: #555;
}

div.click-container {
    width: 10px;
    height: 10px;
}

<div class='lowest'>
    <div class='visual-container'></div>
</div>

<div class='highest'>
    <div class='click-container'></div>
</div>

Now, when the 'highest' element is clicked, the event is dispatched also on the 'lowest' element.

The basic idea:

function onHoverEventForHighest() {
    createMouseEvent(lowest_element, 'mouseover', event);
};

This part is fine and transfers the event accordingly, but it does not seem to invoke the :hover CSS psuedo-class.

Has anyone had any luck with doing something of this nature?

+6  A: 

The :hover pseudo-class is not necessarily known for its reliability. Also, there's no way (that I know of) to control its behaviour via Javascript.

According to the W3C's spec, the :hover pseudo-class should only be applied when the user initiates the action. Quote:

The :hover pseudo-class applies while the user designates an element (with some pointing device), but does not activate it. For example, a visual user agent could apply this pseudo-class when the cursor (mouse pointer) hovers over a box generated by the element. User agents not supporting interactive media do not have to support this pseudo-class.

So, your best best, in this situation, would be to apply a concrete class (let's say .hover) via a function bound to the mouseover and mouseout events of the desired target elements.

As an aside, you could probably save yourself a lot of hassle if you were to re-structure your markup into a hierarchical/nested form, then the DOM would automatically bubble these events for you. That said, see this SO question and answer on how to manually propagate mouse events through absolutely positioned elements.

jason
+1  A: 

Jason's element-nesting comment inspired this:

<style type="text/css">
div.visual-container {
    width: 10px;
    height: 10px;
}

.widget-container:hover div.visual-container {
   background-color: #555;
}

div.click-container {
    width: 10px;
    height: 10px;
}
</style>
...
<div class="widget-container">
  <div class='lowest'>
    <div class='visual-container'></div>
  </div>
  <div class='highest'>
    <div class='click-container'></div>
  </div>
</div>

This may have been the solution Jason was hinting at. As he said, the DOM doesn't give you control over pseudo-classes, but you don't need the DOM for this. Style-y solutions for style-y problems.

outis
Yes, that's one way to approach it. But, what I actually had in mind was that if you ad `visual-container` inside of `click-container` he wouldn't have to manually propagate all his DOM events, like he is--and `:hover` would still work too.
jason
Yeah, that comment minus the typos. :)
jason