Tabeller 'revisited'
Jeg lovte under Scripting med tabeller at det skulle bli julekalenderens siste tabell-innlegg. Desverre begikk jeg en grov blemme i det innlegget som må rettes opp. Før du går videre - klikk deg inn på utgangspunktet og se om du spotter feilen!
Dagens oppgave
Det ferdige resultatet fra sist led under dårlig tilbakefall for brukere uten Javascript. Med tanke på at dette var en av argumentene for at løsningen var elegant er dette en grov tabbe og den må rettes.
Siden vi da først er inne på tabellene igjen tenkte jeg også å legge til en nyttig feature, nemlig fremheving av tabellraden som musepekeren står over.
Den dårlige løsningen
Den dårlige løsningen hadde følgende CSS:
.sortable thead th {
padding-right: 18px;
background: url(arrow_down.gif) 91% 60% no-repeat;
cursor: pointer;
}
Dette er vel og bra for å markere at tabellen er sortérbar, men hva skjer når Javascript ikke er tilgjengelig? Jo, musepekeren tar form av en klikkende hånd, og tabellen viser piler i headingene. Oops! Dette er ikke bra. Vi ønsker at tabellen kun skal indikere klikking og sortering med headingene kun når sortering faktisk er tilgjengelig.
Den gode løsningen
I den gode løsningen må vi bruke en annen krok enn den samme kroken som benyttes for å hekte inn sorterings-scriptet.
class="sortable" sier ingenting om hvorvidt tabellen faktisk er sortérbar. Den sier bare at vi ønsker å sortere tabellen.
Løsningen er å la scriptet legge til et klassenavn til som indikerer at tabellen er berørt av scriptet, og så kan vi bruke denne klassen som krok. Da er vi garantert at den visuelle indikasjonen gis kun når tabellen faktisk er sortérbar.
Scriptet
Det opprinnelige scriptet gjør ikke noe for å hjelpe oss, så vi må modifisere det bittelitt. I sorttable.js finner du en funksjon med navn
makeSortable rundt linje 42. Rett inne i denne funksjonen kan vi sette inn følgende kode:
// Mark table as sortable
table.className += ' is_sortable';
Stilsettet
Når scriptet oppfører seg trenger vi bare en liten justering av den opprinnelige CSS-en:
.is_sortable thead th {
padding-right: 18px;
background: url(arrow_down.gif) 91% 60% no-repeat;
cursor: pointer;
}
Voila! Resultatet kan sees her. (Prøv å laste samme side på nytt uten Javascript).
Fremheving av "aktiv" rad
Fremheving av aktiv rad kan gjøres enkelt med CSS:
tbody tr:hover td, tbody tr:hover th,
tbody tr.alt:hover td, tbody tr.alt:hover th {
background: #fffde9;
}
...ihvertfall for standard-vennlige nettlesere.
IE6 vil ikke kunne vise dette riktig fordi den ikke støtter
:hover-pseudoklassen for elementer utenom
a. Dermed må vi til å scripte litt igjen.
Oppdatert script
Til dette formålet kunne det være greit med en støttefunksjon som bytter et klassenavn av og på. Følgende kode burde gjøre susen:
function toggleClassName(element, className) {
var pattern = new RegExp("\\b" + className + "\\b");
if (pattern.test(element.className)) {
element.className = element.className.replace(className, '');
} else {
element.className += ' ' + className;
}
}
Her sjekker vi om klassen allerede finnes med et regulært uttrykk. Deretter legger vi til klassen om den ikke finnes, eller tar den bort om den finnes.
Den opprinnelige løkka som ga annenhver rad klassen "alt" kan modifiseres som så:
for (var i = 0, table = null; (table = document.getElementsByTagName('table')[i]); i++) {
var tbodies = table.getElementsByTagName('tbody');
var tbody = tbodies.length > 0 ? tbodies[0] : table;
for (var j = 0, row = null; (row = tbody.getElementsByTagName('tr')[j]); j++) {
row.className = j % 2 == 0 ? 'alt' : '';
row.onmouseover = function(e) { toggleClassName(this, 'hover'); };
row.onmouseout = row.onmouseover;
}
}
Med litt støtte fra oppdatert CSS får vi ønsket resultat, også i Internet Explorer:
tbody tr:hover td, tbody tr:hover th,
tbody tr.alt:hover td, tbody tr.alt:hover th,
tbody .hover td, tbody .hover th {
background: #fffde9;
}
Legg merke til at jeg beholder den opprinnelige løsningen. Dette sikrer at vi får aktiv-markering av tabellrader i standardvennlige nettlesere selv uten Javascript.
Mer trøbbel
Men vi er enda ikke ferdige. Da jeg skrev det opprinnelige innlegget ble jeg overrasket over at
IE6 tilllot meg å sette bakgrunn på
thead, noe jeg sjelden praktiserer. Det viste seg når jeg tok dette opp igjen at selvom du kan sette bakgrunn på
thead kan du ikke uten videre sette en ny bakgrunn på
th og forvente å se begge samtidig i
IE6. Sukk.
Løsningen i dette tilfellet er én av to: enten gi Internet Explorer en massiv gråfarge på headingene (altså, skip det ene bakgrunnsbildet), eller å legge et nytt element inne i header-cellene for å kunne kjøre to bakgrunner på headingene. Merk at dette ikke vil være et problem dersom du bruker bakgrunnsfarge fremfor bakgrunnsbilde på headingene.
Enter
span
Vel, jeg liker at ting fungerer godt i nettlesere som mange bruker, så jeg laget en løsning med
span.
Resultatet kan sees her. Det krevde noen endringer i stilsettet:
thead th {
padding: 0;
}
thead th span {
display: block;
padding: 4px 6px;
}
Det skulle være det. Vennligst si ifra om noen finner flere problemer.
Så, opp med hånda alle som så (hoved)problemet (tilbakefallet) i det opprinnelige innlegget!