Reputation: 6618
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>
Upvotes: 3
Views: 237
Reputation: 1075587
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.
Upvotes: 5
Reputation: 413996
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
Upvotes: 3
Reputation: 89402
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.
});
Upvotes: 3