PDA

View Full Version : hover effect on table rows in IE



bobbby
01-15-2006, 10:43 AM
I made a table and when you hover over a row the background color changes

tr:hover {background: black;}

It works in all browsers except IE. I did some research here and now I know that IE doesnt support :hover on non-links.
BUT is there some script genious out there that found an easy way around the shortcomings of IE?

Please note that the effect im looking for is nice but it isnt crucial, so im not gonna write a page of code so IE looks nice. So nevermind if its lots of work.:p

Twey
01-15-2006, 11:19 AM
You have to use Javascript.

<script type="text/javascript">
var t = document.getElementsByTagName("tr");
for(var i=0;i<t.length;i++) {
var ocn = t[i].className;
t[i].onmouseover = function() { t[i].className = "hovered" };
t[i].onmouseout = function() { t[i].className = ocn };
}
</script>
Define a class for your hovered TRs:

<style type="text/css">
tr.hovered {
background-color: black;
color: white;
}
</style>Don't forget to pair every background-color with a color. The script should go before your </body> tag.

bobbby
01-15-2006, 12:34 PM
thanks for the quick reply. I'm taking a well deserved break now but I'm gonna try it tonight, so i'll get back to you.

bobbby
01-15-2006, 05:49 PM
Ok, I give up! I cant seem to get it to work. There are some crucial things missing in my code. I just started learning about CSS yesterday, so my skill level isnt helping me resolve this on my own...

here's my best attempt (which, sadly isnt even close):


<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
<title>Untitled Page</title>
<style type="text/css">
tr.hovered {
background-color: black;
color: white;
}
</style>

</head>

<body bgcolor="#ffffff">
<table width="225" border="1" cellspacing="0" cellpadding="0" bgcolor="#33ff00">
<tr class="hovered">
<td>
<div align="center">1</div>
</td>
<td>
<div align="center">2</div>
</td>
</tr>
<tr class="hovered">
<td>
<div align="center">3</div>
</td>
<td>
<div align="center">4</div>
</td>
</tr>
</table>
<p></p>
<script type="text/javascript">
var t = document.getElementsByTagName("tr");
for(var i=0;i<t.length;i++) {
var ocn = t[i].className;
t[i].onmouseover = function() { t[i].className = "hovered" };
t[i].onmouseout = function() { t[i].className = ocn };
}
</script>
</body>
</html>

Apparently some objects need to be defined, but me and my goldfish dont have a clue... :confused:

Twey
01-15-2006, 09:21 PM
Don't specify the TRs as class="hovered". They have their class dynamically set to that by the script.

mwinter
01-15-2006, 10:30 PM
<script type="text/javascript">
var t = document.getElementsByTagName("tr");
for(var i=0;i<t.length;i++) {
var ocn = t[i&#93;.className;
t[i&#93;.onmouseover = function() { t[i&#93;.className = "hovered" };
t[i&#93;.onmouseout = function() { t[i&#93;.className = ocn };
}
</script>That's broken (and could be better written). The listeners will look-up the value of i when called, which will equal the length property of the collection (and yield undefined). The this operator (and feature detection) should be used instead:



if(document.getElementsByTagName) {
(function() {
var className = 'hovered',
pattern = new RegExp('(^|\\s+)' + className + '(\\s+|$)'),
rows = document.getElementsByTagName('tr');

for(var i = 0, n = rows.length; i < n; ++i) {
rows[i&#93;.onmouseover = function() {
this.className += ' ' + className;
};
rows[i&#93;.onmouseout = function() {
this.className = this.className.replace(pattern, ' ');
};
}
rows = null;
})();
}
Mike

bobbby
01-16-2006, 05:34 AM
Thank you both for helping me out, but it is proven to be a tougher nut to crack than anticipated. Mike, I used your code instead and it works fine, except the rows remain black. I can see there is a mouseout function in your code but it doesnt seem to be doing anything. I would like the rows to return to their begin-state on mouseout. Is that possible?

mwinter
01-16-2006, 12:00 PM
Sorry, the regular expression was broken. :( I've edited my previous post to include the fix, though it's a fairly simple change you could edit yourself: where you see the two backslashes in the RegExp constructor, add an extra one to each (that is, \ -> \\).

Mike

bobbby
01-16-2006, 12:24 PM
Now that you told me, it's so obvious!

Well, it's working like a charm now, so you made another script-handicapped person happy.

Thanks

chrisf
09-20-2006, 08:56 PM
hi Mike, I need some help, instead of having a table row color changed on hover, my target is table's cell. though i still can't figure out how to use your code. My sample is at: http://www.sparklerange.com/menu.html

I look at your: http://www.mlwinter.pwp.blueyonder.co.uk/clj/easyrider/table.html

It's even longer... to figure out, I don't need striped color. Only just hover color for table's cell for IE6.

Many thanks in advance!
Chris

blm126
09-20-2006, 09:00 PM
if(document.getElementsByTagName) {
(function() {
var className = 'hovered',
pattern = new RegExp('(^|\\s+)' + className + '(\\s+|$)'),
rows = document.getElementsByTagName('td');

for(var i = 0, n = rows.length; i < n; ++i) {
rows[i].onmouseover = function() {
this.className += ' ' + className;
};
rows[i].onmouseout = function() {
this.className = this.className.replace(pattern, ' ');
};
}
rows = null;
})();
}

The variable names don't make much sense but this should work.

chrisf
09-20-2006, 09:09 PM
thanks for your prompt reply blm126, i am stucked. how is the CSS part like? Do I also need to apply a class or ID to each TD tag manually? sorry.

Is this correct:

<style type="text/css">
td.hovered {
background-color: black;
color: white;
}
</style>

chrisf
09-20-2006, 09:37 PM
OK, i got it work by changing any TR occurance to TD, and "rows" to "cell".. in the jscript. thanks!

mwinter
09-20-2006, 11:14 PM
hi Mike, I need some help, instead of having a table row color changed on hover, my target is table's cell. though i still can't figure out how to use your code.

The table striping code you referenced (and are trying to use), aside from being rather dated, isn't at all appropriate for cell highlighting. The code from earlier in this thread (which blm126 modified) would be better suited to the task.



how is the CSS part like?



td:hover, td.hovered {
background: #rrggbb;
}

No attributes need to be added to the table cells. The script, however, would need to be included after the table(s) in question for it to work.



OK, i got it work by changing any TR occurance to TD, and "rows" to "cell".. in the jscript.

If you meant that you hacked the table striping code, don't. As I wrote above, it's simply not the right thing to use.

Mike

ItsMeOnly
09-21-2006, 01:57 PM
not to barge in on anyone's territory but isn't this an elegant solution:


function setcolor(widget, color) {
var widget = document.getElementById(widget);
widget.style.background = color;
}

and naming tr's while either looping thru script, or manually:

<tr id="row4" onmouseover="setcolor('row4', '#eedd8c');"
onmouseout="setcolor('row4', 'transparent');">[...]</tr>

mwinter
09-21-2006, 06:21 PM
not to barge in on anyone's territory but isn't this an elegant solution:


function setcolor(widget, color) {
var widget = document.getElementById(widget);
widget.style.background = color;
}

and naming tr's while either looping thru script, or manually:

<tr id="row4" onmouseover="setcolor('row4', '#eedd8c');"
onmouseout="setcolor('row4', 'transparent');">[...]</tr>

No, not really. Better would be:



function setColour(element, colour) {
if (element.style) element.style.color = colour;
}



<tr onmouseover="setColour(this, '#eedd8c');" onmouseout="setColour(this, '');">

but it's still not very elegant: it requires adding attributes to every row in the table, which is rather tedious and bloats the markup.

By the way, do use feature detection. Don't just assume that objects and methods are always supported.

Mike

Twey
09-21-2006, 06:31 PM
Mike: How well supported is element.style in modern browsers (and common special cases where the user is unable to upgrade any further)?

mwinter
09-21-2006, 06:54 PM
How well supported is element.style in modern browsers

If by modern, you also imply common, then the answer is "completely". Beyond that, I couldn't say as I only have a limited set of browsers, but there's little reason not to perform the test. Having code error out is, in my opinion, a terrible impression to make upon users.

Feature testing has very little impact on performance, and the flexible nature of ECMAScript allows for a testing strategy that, upon definite success or failure, can be replaced with streamlined code.

Mike

zachvenice
10-16-2006, 04:16 AM
First of all, this is a great thread. Thanks for all your hard work. My question is how would you apply this to only a specific table on a page? Would this be set up through an ID? Thanks again.

z

mwinter
10-16-2006, 02:24 PM
My question is how would you apply this to only a specific table on a page? Would this be set up through an ID?

In part, yes. Rather than calling the getElementsByTagName method of the document object, you'd first obtain a reference to the table and call the method of that element. However, if there are nested tables (rare in a well-written site), things will become a little more complicated than the modified code, below:



if (document.getElementById) {
(function() {
var element;

if ((element = document.getElementById('table-identifier'))
&& element.getElementsByTagName) {
var className = 'hovered',
pattern = new RegExp('(^|\\s)' + className + '(\\s|$)'),
rows = document.getElementsByTagName('td');

for (var i = 0, n = rows.length; i < n; ++i) {
rows[i].onmouseover = function() {
this.className += ' ' + className;
};
rows[i].onmouseout = function() {
this.className = this.className.replace(pattern, ' ');
};
}
rows = null;
})();
}

replacing table-identifier as appropriate.

Mike

geoffgarcia
09-21-2007, 09:54 PM
if(document.getElementsByTagName) {
(function() {
var className = 'hovered',
pattern = new RegExp('(^|\\s+)' + className + '(\\s+|$)'),
rows = document.getElementsByTagName('tr');

for(var i = 0, n = rows.length; i < n; ++i) {
rows[i].onmouseover = function() {
this.className += ' ' + className;
};
rows[i].onmouseout = function() {
this.className = this.className.replace(pattern, ' ');
};
}
rows = null;
})();
}
How can I modify this code to restrict it to a particular table?

Twey
09-22-2007, 11:47 AM
Replace this:
document.getElementsByTagName('tr');with this:
document.getElementById('id_of_your_table').getElementsByTagName('tr');

geoffgarcia
09-24-2007, 06:53 PM
Replace this:
document.getElementsByTagName('tr');with this:
document.getElementById('id_of_your_table').getElementsByTagName('tr');

Is there any way to do this if the table doesn't have an ID or class associated with it?

I'm working with a bit of code that is generated through a DLL (which can't be edited) that presents a series of tables without IDs or classes.
The layout is in a format like:
<table>
<tr>
<td></td>
</tr>
</table>
<table>
<tr>
<td></td>
</tr>
</table>

and it would be the second table to which I'd like to apply this code.

steppen
01-23-2009, 12:56 PM
Hi! I have a doubt:


tr{background:#feffee;color:#333;hover:expression(this.onmouseover=new Function("this.style.background='#d8d9cc';"),this.onmouseout=new Function("this.style.background='#feffee';"));}


I have this code above on my CSS to make hover effect. Onmouseover works like spected, but onmouseout it just changes the colour of my rows because I have alternate colours on them. The question is: how can I programmaticly say that I want the same colour as it was before?
I don't have much experience on CSS and js...

Thanks in advance.