Vytvořte si vertikální posuvník

25. ledna 2002

V jednom z článků jste si mohli přečíst, jak upravit barvy scrollbaru pro Internet Explorer. Zkusili jste si ale vytvořit zcela libovolný posuvník?

Nejdříve se pokusím načrtnout základní ideu řešení. Vytvořte si HTML stránku skládající se ze dvou rámů.

<HTML>
<HEAD>
<TITLE>Scrollbar</TITLE>
</HEAD>
<FRAMESET border=0 cols=*,15 frameBorder=0 frameSpacing=0>
<FRAME scrolling=no id=left name=left noResize src=“stranka.htm“>
<FRAME scrolling=no id=posuvnik name=posuvnik noResize src=“posuv.htm“>
</frameset>
<NOFRAMES>
<body>
Vas prohlizec bohuzel nepodporuje framy
</body>
</NOFRAMES>
</HTML>

V levém rámu budete zobrazovat obsah stránky, v pravém posuvník. Největší problém ale bude zjistit, jak je dlouhý dokument (v pixelech). To můžete udělat tak, že si v levém rámu vytvoříte dvousloupcovou tabulku. V levém zobrazíte obrázek široký jeden pixel a v pravém to hlavní pro uživatele – obsah celé stránky (stranka.htm):

<HTML>
<HEAD>
</HEAD>
<BODY>
<table id=hlata style=“position:absolute;TOP:0pt;LEFT:0pt;“ border=0 cellpadding=0 cellspacing=0 id=tabulka height=1%> <tr>
<td>
<img id=obraz src=“nic.gif“ height=100%>
</td>
<td>
// libovolně dlouhý obsah stránky
</td>
</tr>
</table>
</BODY>
</HTML>

A jak bude vypadat vlastní scrollbar v pravém rámu? Vytvořte si soubor posuv.htm vypadající asi takto:

<HTML>
<HEAD>
</HEAD>
<BODY id=body onclick=“klepnuto()“ style=“margin:0px“>
<img id=nahoru onmouseover=“jednahoru()“ onmouseout=“zastav()“ STYLE=“position:absolute;TOP:5px;LEFT:0px;“ src=“sipu.gif“>
<img id=scrlr STYLE=“position:absolute;TOP:0px;LEFT:0px;“ src=“scroller.gif“>
<span style=“display:none“ id=pomoc>0</span><br>
<img id=dolu onmouseover=“jeddolu()“ onmouseout=“zastav()“ STYLE=“position:absolute;TOP:0px;LEFT:0px;“ src=“sipd.gif“>
</BODY>
</HTML>

Obrázek „nahoru“ tvoří horní šipku, „dolů“ dolní šipku a „scrlr“ je obrázek pro posuvník. Účel tagu span vám vysvětlím později.

Definujte si několik proměnných. Jejich význam bude zřejmý z dalšího popisu:

<script>
var odsad_dole=100; // jak daleko od dolního okraje má být dolní šipka
var skok=5; // délka scrollu při najetí na šipku
var cas=100; // doba mezi dvěma posunutími při najetí na šipku
var tiou; // pomocná
// sem vkládejte všechny funkce
</script>

Teď se pokusím popsat funkce vyskytující se v souboru posuv.htm. Budu postupovat od jednodušších ke složitějším.

<script for=window event=onload> // proveď při nahrání
dolu.style.top=body.clientHeight-odsad_dole; // umísti dolní šipku
scrlr.style.top=nahoru.style.pixelTop+nahoru.offsetHeight // umísti posuvník pod horní šipku
</script>

Při najetí na horní šipku se provede tato funkce:

function jednahoru(){
var newtop;
newtop=scrlr.style.pixelTop-skok; // přesuň posuvník nahoru o ‚skok‘ pixelů
if (newtop<(nahoru.style.pixelTop+nahoru.offsetHeight)) newtop=nahoru.style.pixelTop+nahoru.offsetHeight; // zabraň posuvníku, aby jel neustále nahoru, zastav ho u horní šipky
parent.left.window.scrollTo(0,(newtop-(nahoru.style.pixelTop+nahoru.offsetHeight))*((parent.left.obraz.height-body.clientHeight)/(body.clientHeight-(odsad_dole+nahoru.style.pixelTop+
nahoru.offsetHeight+scrlr.offsetHeight))));
pomoc.innerText=(newtop-(nahoru.style.pixelTop+nahoru.offsetHeight))*((parent.left.obraz.height-body.clientHeight)/(body.clientHeight-(odsad_dole+nahoru.style.pixelTop+
nahoru.offsetHeight+scrlr.offsetHeight)));
scrlr.style.pixelTop=newtop;
tiou=setTimeout(„jednahoru()“,cas); // opakuj funkci po uplynutí stanoveného času
}

Asi nejhorší (ale také nejdůležitější) je řádek „parent.left… Je poměrně složité vysvětlit jeho význam, ale pokusím se o to. Část ((parent.left.obraz.height-body.clientHeight)/(body.clientHeight-(odsad_dole+nahoru.style.pixelTop+nahoru.offsetHeight+scrlr.offsetHeight)) stanovuje jakýsi index posunutí, vytvořený jako „(výška_levého_dokumentu-výška_okna)/(nejmenší_vzdálenost_šipek-výška_posuvníku)“. Tento index udává, o kolik se má posunout levé okno, změní-li se pozice posuvníku o 1 pixel. Část „(newtop-(nahoru.style.pixelTop+nahoru.offsetHeight))“ udává vzdálenost posuvníku od horní šipky. Vynásobíte-li tato dvě okna, zjistíte, kam máte pomocí funkce scrollTo posunout levý dokument. Smysl toho záhadného „pomoc“ vysvětlím až na závěr. Řádek „scrlr.style.pixelTop=newtop“ mění pozici posuvníku na hodnotu určenou dříve.

Funkce pro najetí na dolní šipku bude vypadat téměř stejně:

function jeddolu(){
var newtop;
newtop=scrlr.style.pixelTop+skok; // přesuň posuvník dolů o ‚skok‘ pixelů
if (newtop>body.clientHeight-(odsad_dole+scrlr.height)) newtop=body.clientHeight-(odsad_dole+scrlr.height); // zabraň posuvníku, aby jel neustále DOLŮ, zastav ho u DOLNÍ šipky
parent.left.window.scrollTo(0,(newtop-(nahoru.style.pixelTop+nahoru.offsetHeight))*((parent.left.obraz.height-body.clientHeight)/(body.clientHeight-(odsad_dole+nahoru.style.pixelTop+
nahoru.offsetHeight+scrlr.offsetHeight))));
pomoc.innerText=(newtop-(nahoru.style.pixelTop+nahoru.offsetHeight))*((parent.left.obraz.height-body.clientHeight)/(body.clientHeight-(odsad_dole+nahoru.style.pixelTop+
nahoru.offsetHeight+scrlr.offsetHeight)));
scrlr.style.pixelTop=newtop;
tiou=setTimeout(„jeddolu()“,cas); // opakuj funkci po uplynutí stanoveného času
}

Když uživatel sjede z šipky, je potřeba zastavit průběh funkce setTimeout. Provedete to celkem jednoduše:

function zastav()
{
clearTimeout(tiou);
}

Ještě zbývá ošetřit případ, kdy se uživatel pokusí pohnout s vlastním posuvníkem. Nejdříve mu musíte zajistit, aby při pokusu o přesun scrollbaru nastala standardní „přesunovací“ operace, a nezobrazilo se jen přeškrtnuté kolečko. Další funkce vám k tomu bohatě postačí:

function UmozniPresun() {
if (event.srcElement.id==“scrlr“) // jesliže je vybrán scrollbar
event.returnValue=false; // umožni přesunutí
}
document.ondragstart = UmozniPresun; // přiřaď funkci k události ondragstart

Při přesunu posuvníku se udělá zhruba to samé, jako při najetí na šipku.

function PohybMysi() {
var newtop;
if (event.button==1) { // je-li stisknuto levé tlačítko, …
newtop=event.clientY-(scrlr.offsetHeight/2) //… přesuň posuvník na pozici myši
if (newtop<(nahoru.style.pixelTop+nahoru.offsetHeight)) newtop=nahoru.style.pixelTop+nahoru.offsetHeight; // neumožni přejezd přes dolní šipku
if (newtop>body.clientHeight-(odsad_dole+scrlr.height)) newtop=body.clientHeight-(odsad_dole+scrlr.height); // neumožni přejezd přes horní šipku
parent.left.window.scrollTo(0,(newtop-(nahoru.style.pixelTop+nahoru.offsetHeight))*((parent.left.obraz.height-body.clientHeight)/(body.clientHeight-(odsad_dole+nahoru.style.pixelTop+
nahoru.offsetHeight+scrlr.offsetHeight))));
pomoc.innerText=(newtop-(nahoru.style.pixelTop+nahoru.offsetHeight))*((parent.left.obraz.height-body.clientHeight)/(body.clientHeight-(odsad_dole+nahoru.style.pixelTop+
nahoru.offsetHeight+scrlr.offsetHeight)));
scrlr.style.pixelTop=newtop; // vysvětleno nahoře
} } document.onmousemove = PohybMysi; // spusť funkci při pohybu myši

Na závěr vysvětlení onoho zdánlivě zbytečného tagu „span“. Ti pozornější si jistě všimli, že obsahuje pozici, na kterou se scrolloval levý rám. Zkuste si schválně označit text v příkladu a jet stále dolů. Jakmile pustíte tlačítko myši, v okně se zobrazí přesně to, co v něm bylo předtím, než jste začali výběr. Je to umožněno skriptem v souboru stranka.htm, který má tuto podobu:

<SCRIPT FOR=document EVENT=onmouseup>
window.scrollTo(0,parent.posuvnik.pomoc.innerText)
</SCRIPT>

Onen záhadný tag scroll tedy říká, kam se má okno vrátit poté, co uživatel pustí tlačítko myši. Tuto funkci by sice bylo možné vynechat, ale pokud tak uděláte, může se vám stát, že jakmile označíte úsek textu (viz výše), nebude posuvník ukazovat správnou pozici. Tahle funkce je téměř nejjednodušším způsobem, jak situaci ošetřit. Ještě lehčí by bylo zakázat výběr textu v celém souboru, ale to by se mnohým uživatelům nelíbilo.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Předchozí článek Abeceda formuláře

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *