3

I have a table full of cells and i would like to get on which cell the mouse is.

For this i have attached events to all the cells and then i am finding the elements. But i guess there could be a better options. right ?

Is it possible that i attach only single event handler on top and still be able to catch all the information. like which cell user is currently on etc.

Something like below,

<table onMouseOver="monitorFuntion(event)" >...</table>
1
  • 1
    :) its very difficult to select only one answer when all are good and nice. Thanks all. Commented Apr 22, 2010 at 12:53

3 Answers 3

5

It's possible to do exactly what you said: You can put a handler on the table, and then find the cell from that. (This is sometimes called "event delegation".) You can do this for some events, including mouseover and mouseout, because they bubble. You can't do it for other events (like blur or focus) because they don't bubble.

Suppose you have a table with the ID "myTable". You can hook up an event handler for mouseover:

var table = document.getElementById("myTable");
if (table.attachEvent) {
    table.attachEvent("onmouseover", handleMouseOver);
}
else {
    table.addEventListener("mouseover", handleMouseOver);
}

And then handle it like this:

function handleMouseOver(event) {
    var target;

    // Handle IE event difference from standard
    event = event || window.event;

    // Find out what element the event actually happened on
    // (Another IE difference here, srcElement vs target)
    target = event.srcElement || event.target;

    // Since that might be an element *within* your cell (like
    // a link, or a `span`, or a `strong`, etc.), find the cell
    while (target && target.tagName != "TD" && target.tagName != 'BODY') {
        target = target.parentNode;
    }
    if (target && target.tagName != 'BODY') {
        // Found one, `target` now points to the cell the mouse is over
    }
}

Note that it's important you handle the case where target ends up being null or referring to the body element, because you'll get this event over the table's borders, row padding, etc.

Javascript libraries can help you with this a lot. For instance, the above using Prototype looks like this:

$("myTable").observe("mouseover", handleMouseOver);

function handleMouseOver(event) {
    var target;

    target = event.findElement("td");
    if (target) {
        // ...
    }
}

jQuery, Closure, and others will similarly help quite a bit.

Sign up to request clarification or add additional context in comments.

2 Comments

Ha ha almost exactly the same opening sentence :-)
@Russ: Thanks! Fixed. (Been using libraries for so long...)
3

Based on the code snippet you posted you are looking for event delegation.

Step 1: use jQuery 1.4.2 +

Step 2:

// you can use move, enter, out, over whatever...
$("table").delegate("mouseenter", "td", click, function(){
    var tableCell = $(this); // the cell which is currently moused-over.
});

Comments

3

Yes, you can do exactly that, and then use the event object to find the element. The event object differs between IE and other browsers, but getting the "target" is about the same:

 function handler(ev) {
   ev = ev || window.event;
   var targetElement = ('target' in ev) ? ev.target : ev.srcElement;
   // ...
 }

Now not all events will "bubble up" for you, but I think that the mouse events do. The problems are mostly with "change". Frameworks like jQuery or Prototype generally try to give you more normalized behavior.

edit fixed for IE compatibility

1 Comment

@Russ Cam - Ah ok; it's been a while since I actually wrote code like that instead of just using Prototype or jQuery! I'll fix it. Thanks!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.