Efektivní rollover (hover) na řádku tabulky

05.08.2004 15:27

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.

Komentáře k příspěvku 'Efektivní rollover (hover) na řádku tabulky'

  1. Daniel Steigerwald:

    Dobrý článek, ale já nato šel trochu jinak. Vše jsem ostyloval čistě CSS a pro IE použil hover.htc emulaci, kterou všichni jistě znáte. Jen je třeba dávat pozor, a nepřiřadit behaviour příliš elementům, jinak to přohlížeč nebude stíhat.

  2. Danny:

    Vím, že bylo testováno jen v IE, jen pro doplnění - v Opeře se příklad č. 4 zobrazuje zvláštně, při pohybu sloupcem se nezabarví celé buňky, při přechodu do vedlejšího sloupce se celý řádek dobarví.

  3. Spike:

    Souhlasím s Danielem . Zde najdete více informací k *:hoveru pro IE.

    1) Moderní prohlížeče (i s vypnutým js) použijí pseudotřídu tr:hover.

    2) pro IE se do css přidá pouze

    tr { behaviour: url(’hover.htc’) }
    tr:hover, tr.hover { … }

    ten hover.htc vlastně převede třídu .hover na js funkci onMouseOver() resp. onMouseOut().

    Jediný bug, na který jsem u této verze hover.htc (na webu jich je víc) je ten, že pokud na takovýto prvek najedu myší ještě před úplným načtením stránky, dojde k jeho chybnému vykreslení (asi se na něj nepoužije daný styl).
    U řádku tabulky jsem ještě nikdy nezkoušel, vetšinou to používám např. na zvýraznění odkazů v daném odstavci.

Zanechte komentář k příspěvku

XHTML: Můžete použít následující tagy: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>