Choseho weblog o webu

Efektivní rollover (hover) na řádku tabulky

V poslední době pozoruji takový zajímavý trend. Když vytvářím nějaký web, který má tabulkový výpis dat, tak zpravidla od grafika dostanu návrh, ve kterém je krásně namalovaná tabulka s ukázkou rollover efektu na řádku. Nemám nic proti tomuto efektu (spíše "feature"), je to IMHO velice užitečná věc a uživatel se v případě delšího řádku neztratí, ale chtěl bych se spíše zajímat o tu technickou, realizační, část.

CSS a JavaScript

Jednoduché řešení je v nových prohlížečích, které podporují CSS vlastnost :hover na jakýkoliv prvek. Toto řešení ovšem v současné době je téměř nepoužitelné. Proto se musím odklonit k javascriptu a DOM, který dokáže poměrně spolehlivě pomoci. Zkoušel jsem několik řešení a sledoval, jak jednotlivé řešení zatěžuje CPU. Jen pro informaci - měření bylo čistě subjektivní, bez použití jakýchkoliv speciálních nástrojů nebo utilit a testoval jsem vždy jen IE (pokud nejste jeho fanda, tak máte smůlu, ale zatím ho má pořád většina běžných uživatelů).

Příklady

Všechny příklady mají stejný základ. Chci měnit podbarvení tabulky nezávisle na barvě, kterou řádek měl předtím. Pokud by tabulky byla "zebrovaná", znamenalo by to samozřejmě jisté komplikace kódu, ale velký problém to není. Dále by bylo ideální řešení, které by umožňovalo barvu hover efektu měnit z externího stylového předpisu. Data pro ukázkovou tabulku jsem získal z webu Yuhůa.

Řešení 1

Snad téměř nejkratší řešení co se týče velikosti skriptu, používá barvu ze stylového předpisu a řádku při onmouseover přiřadí třídu "aktivni".

<script type="text/javascript">
function highlight_row(obj,w) {
	if (w == 1) obj.className = 'aktivni';
	else obj.className = '';
}
</script>
# řádek v tabulce: #
<tr onmouseover="highlight_row(this,1);"  onmouseout="highlight_row(this,0);">

Použití na ukázkové stránce (příklad 1). Technicky ideální řešení, ale při testu se ihned ukáže, že už při pomalejším pohybu kurzorem nad tabulkou je vytížení CPU na 100%.

Řešení 2

U toho řešení jsem zkusil jít zcela jinou cestou. Další možnost je měnit pozadí pomocí vlastnosti background-color na buňce v tabulce. Když jsem zkoušel měnit pozadí na řádku (tr) přes javascript, tak to prohlížeč tvrdošíjně odmítal, na rozdíl od buňky (td).

<script type="text/javascript">
function highlight_row(obj,w,color){
	var tds = obj.getElementsByTagName('td');
	for(i=0;i < tds.length;i++) {
		if (w == 1) {
			tds[i].style.backgroundColor = color;
		} else tds[i].style.backgroundColor = "";
	}
}
</script>
# řádek v tabulce: #
<tr onmouseover="highlight_row(this, 1, '#CCFFCC');" 
	onmouseout="highlight_row(this, 0, '#CCFFCC');">

Ukázková stránka (příklad 2). Z ukázkového skriptu je zřejmé, že je nutné barvu definovat v HTML, což není úplně to, co by jsem chtěl. Co se týče CPU, tak tento příklad je na tom velmi dobře a potřebuje k provozu cca 20-30% CPU.

Řešení 3

Vycházel jsem z příkladu 2. Cílem bylo získat barvu pro řádek tabulky z CSS. Díky funkcím getComputedStyle (Gecko) a currentStyle (IE) se mi podařilo získat potřebnou barvu ze stylového předpisu a aplikovat jí na řádek v tabulce. To si ovšem vyžádalo pomocný prvek ve stránce, který má nadefinovanou barvu, kterou si javascriptem přečtu.

<script type="text/javascript">
var hover_color = null;
function highlight_row(obj,w){
	if (hover_color == null) hover_color = getStyle('hover', "color");
	var tds = obj.getElementsByTagName('td');
	for(i=0;i < tds.length;i++) {
		if (w == 1) {
			tds[i].style.backgroundColor = hover_color;
		} else tds[i].style.backgroundColor = "";
	}
}	
function getStyle(el, style) {
	if(!document.getElementById) return;
	el = document.getElementById(el);
	var value = el.style[style];
	if(!value) {
		if(document.defaultView)
			value = document.defaultView.>
			>getComputedStyle(el, "").getPropertyValue(style);
		else if(el.currentStyle)
			value = el.currentStyle[style];
		return value;
	}
	
}
</script>
# řádek v tabulce: #
<tr onmouseover="highlight_row(this, 1);" onmouseout="highlight_row(this, 0);">
# pomocný prvek #
<span id="hover"></span>

Vše je dobře vidět na příkladu 3. Rychlost je téměř stejná jako u příkladu 2 a navíc máme barvu z CSS. Dle mého názoru zatím nejpřijatelnější řešení. Sice sebou nese nutnost definovat barvu v nějakém prvku ve stránce, nicméně nemusíme vůbec sahat do HTML pro případ změny barev. Co se týká podpory v prohlížečích, tam kde se neujme javascript, lze použít klasickou vlastnost :hover v CSS.

Doplněno 6.8.2004:


Příklad 4

Honza Dvořák mi emailem poslal výborný tip díky kterému jsem udělal další řešení, viz. příklad 4. Na tomto řešení je perfektní, že nemusíte vypisovat inline volání javascriptových funkcní na každém řádku, ale funkce zavěsíte pomocí jednoduchého JavaScriptu automaticky na všechny řádky tabulky. Navíc zavěšování proběhne pouze v IE.

<script type="text/javascript">
var hover_color = null;
function highlight_row(obj,w){
	if (hover_color == null) hover_color = getStyle('hover', "backgroundColor");
	var tds = obj.getElementsByTagName('td');
	for(i=0;i < tds.length;i++) {
		if (w == 1) {
			tds[i].style.backgroundColor = hover_color;
		} else tds[i].style.backgroundColor = "";
	}
}
function getStyle(el, style) {
	el = document.getElementById(el);
	var value = el.style[style];
	if(!value) value = el.currentStyle[style];
	return value;
}
function hover_init() {
	if (document.all && document.getElementById && !window.opera) {
		table = document.getElementById('htabulka');
		trs = table.getElementsByTagName('tr');
		for(var i = 0; i < trs.length; i++){
			trs[i].onmouseover = function(){ highlight_row(this,1); }
			trs[i].onmouseout = function(){ highlight_row(this,0); }
		}
	}
}
window.onload = hover_init;
</script>
# řádek tabulky #
<tr>

Vzhledem k tomu, že řešení vychází z příkladu 3, je vytížení CPU minimální. Co se týče ostatních prohlížečů, je to již kompletní a funkční řešení. Již se těším, až budu moci tento způsob použít na nějakém webu.

Autor: Chose| 15:27 - | Trvalý odkaz | Homepage



© 2004 Josef Šíma - ja@chose.cz