![]() |
![]()
![]()
![]() ![]() ![]() ![]() ![]()
![]()
![]() ![]()
![]() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
Chceme-li mít možnost vyhledávat v textu stránek, zobrazených na CD jako HTML menu, máme nejméně tři možnosti:
- Použít samostatný obslužný program.
- Použít windows scripting host a metody objektu FileSystemObject.
- Uložit texty stránek do nějaké struktury a tu zobrazovat a prohledávat pomocí JavaScriptu.
Každý z těchto způsobů má své výhody a nevýhody. My si v tomto článku popíšeme způsob třetí, který vyžaduje pouze prohlížeč se zapnutým JavaScriptem, což je v současné době u většiny uživatelů téměř standardní vybavení (pro puristy dodávám, že uživatele bez JavaScriptu lze vcelku jednoduše detekovat a věnovat jim speciální verzi HTML menu, bez možnosti vyhledávání).
Podívejme se na ukázku fiktivního CD fiktivní firmy, plné fiktivních produktů a fotografií (odkazy na spustitelné soubory jsou nefunkční, fotografie v ukázce zahrnuty jsou). Vyzkoušejte si procházení celé úrovně menu, případně vyhledávání některých klíčových slov (například „foto“, „program“ apod.)
Použitý JavaScript
HTML soubor, uvedený v příkladu, se jmenuje sample_cdmenu.htm. Veškeré odkazy v použitých skriptech jsou směřovány na tento soubor. Při přejmenování je tedy potřeba příslušné odkazy upravit nebo modifikovat skript, například s použitím location.pathname.
Jádrem celého řešení je objekt Menu, který slouží především jako úložiště textů a odkazů. Pokud máme veškeré zobrazené texty uloženy na jednom místě, lze je později snadno prohledávat. Zde si ukážeme základ kódu objektu Menu, tedy jeho metody a vlastnosti použité při ukládání dat. Kód dalších metod objektu Menu, sloužící k prohledávání a dalším funkcím, uvedeme níže. Pomocná proměnná lastid je použita ke generování unikátního id pro každé vytvořené menu. Zbytek kódu je triviální:
function Menu( title, txt ) {
this.title = title;
this.txt = txt;
this.id = lastid++;
this.submenuscount = 0;
this.submenus = new Array()
this.linkscount = 0;
this.linkurls = new Array()
this.linktexts = new Array()
this.AddMenu = function( mnu ) {
this.submenus[this.submenuscount] = mnu
this.submenuscount++;
}
this.AddLink = function( txt, url ) {
this.linktexts[this.linkscount] = txt;
this.linkurls[this.linkscount] = url;
this.linkscount++;
}
}
Strukturu konkrétního menu vytvoříme opakovaným vytvářením nových objektů třídy Menu a jejich spojováním pomocí metody AddMenu. K vytvoření „finálních“ odkazů na externí stránky, obrázky či produkty slouží metoda AddLink. Konkrétní kód pak může vypadat například takto:
Menus.AddMenu( m1 = new Menu( "Fotografie", "Vyberte si kategorii fotografií.") );
m1.AddMenu( m2 = new Menu( "Vedení", "Toto jsou naši hlavouni:" ) );
m2.AddLink( "Pepa, ředitel", "pepa.jpg" );
m2.AddLink( "Franta, náměstek", "franta.jpg" );
m1.AddMenu( m2 = new Menu( "Kancelář", "Sekretářky a jiné:" ) );
m2.AddLink( "Janička", "jana.jpg" );
m2.AddLink( "Lucinka", "lucie.jpg" );
m2.AddLink( "Martička", "marta.jpg" );
m1.AddMenu( m2 = new Menu( "Dělníci", "Tito lidé nás všechny živí:" ) );
m2.AddLink( "Zdeněk, výroba software", "zdenek.jpg" );
m2.AddLink( "Tomáš, odhánění dotěrných zákazníků", "tomas.jpg" );
Menus.AddMenu( m1 = new Menu( "Software", "Vyberte si typ software." ));
m1.AddMenu( m2 = new Menu( "Naše programy", "Naše skvělé produkty:" ) );
m2.AddLink( "Operační systém Krach 2001", "krach/krach.exe" );
m2.AddLink( "Prohlížeč obrázků", "imgview/setup32.exe" );
m1.AddMenu( m2 = new Menu( "Service packy", "Tyto programy napravují chyby, které jsme udělali ve starších verzích našich programů:") );
m2.AddLink( "Service pack 1 k operačnímu systému Krach 2001", "sp/sp1setup.exe" );
m2.AddLink( "Service pack 1a k service packu 1", "sp/sp1asetup.exe" );
m2.AddLink( "Service pack 1aB k service packu 1a k service packu 1", "sp/sp1aBsetup.exe" );
Dalším úkolem je zjistit, které konkrétní menu máme právě zobrazit (ID tohoto menu je předáváno v URL adrese). K tomu slouží následující kód, který zároveň v případě, že bylo žádáno vyhledávání, získá z URL hledaný řetězec. Menu, které se má zobrazit, je uloženo do pomocné proměnné aMenu. Pokud byl hledán řetězec, je tento uložen do proměnné strtofind:
var strtofind="";
if((index = location.search.indexOf("?"))!=-1) {
if((i2 = location.search.indexOf("find="))!=-1) {
var pomstr = location.search.slice(i2+5);
if((i2 = pomstr.indexOf("&"))!=-1) pomstr = pomstr.slice(0,i2);
strtofind = unescape(pomstr);
} else {
var pomstr = location.search.slice(index+4)
if( pomstr.length > 0 ) id = Math.ceil(pomstr);
}
}
var aMenu = Menus.GetMenuByID(id);
V posledním řádku předchozího kódu je použita metoda GetMenuByID objektu Menu. Tato metoda hledá rekurzivně ve struktuře menu to jedno jediné s odpovídajícím ID a její kód vypadá následovně:
var x,i;
if ( theId==this.id ) return this;
for( i=0; i<this.submenuscount; i++ ) {
x = this.submenus[i].GetMenuByID(theId);
if ( x != null ) return x;
}
return null;
}
V místě stránky, ve kterém si přejeme vypsat texty právě zvoleného menu a odkazy na další úrovně menu, použijeme kód, který může vypadat třeba takto (konkrétní formátování lze samozřejmě upravit dle potřeby):
document.write("<h1>"+aMenu.title+"</h1>");
document.write(aMenu.txt+"<br><br>");
var i;
for(i=0;i<aMenu.submenuscount;i++) {
document.write('<a href="sample_cdmenu.htm?id='+aMenu.submenus[i].id+'">'+aMenu.submenus[i].title+'</a><br>');
}
for(i=0;i<aMenu.linkscount;i++) {
document.write('<a href="'+aMenu.linkurls[i]+'">'+aMenu.linktexts[i]+'</a><br>');
}
}
K vyhledávání použijeme ve vhodném místě stránky formulář s následujícím HTML kódem („podivné“ odesílání výsledků přes handler události onSubmit je zde proto, aby bylo zachováno správné kódování českých znaků):
Vyhledávání:<br>
<input type="text" value="" name="find" size="10"> <input type="submit" name="s" value="Najdi">
</form>
Poté, co uživatel odešle formulář, je do proměnné strtofind uložen hledaný text (viz kód uvedený výše). Zbývá prohledat uložená data a výsledky zobrazit ve formě jednoduché tabulky s odkazy na nalezené dokumenty. Výpis výsledků zajistí následující kód...
document.write("<h1>Výsledky vyhledávání</h1>");
Menus.WriteFindResults(strtofind);
if(found)
document.write("<p>Hledaný text byl nalezen "+found+" x</p>");
else
document.write("<p>Hledaný text nebyl nalezen.</p>");
}
...v kombinaci s pomocnou proměnnou found, uchovávající počet nalezených výsledků, a novou metodou (opět použijeme rekurzi) WriteFindResults objektu Menu:
// v hlavičce stránky
var found=0;
// v kódu objektu Menu
this.WriteFindResults = function( strfind ) {
var i,s1;
s1=this.title.toLowerCase() + this.txt.toLowerCase();
if( s1.indexOf(strfind.toLowerCase())!=-1) {
document.write('<a href="sample_cdmenu.htm?id='+this.id + '">' + this.title + '</a><br>');
found++;
}
for( i=0; i<this.submenuscount; i++ ) {
this.submenus[i].WriteFindResults(strfind);
}
}
Uvedený kód lze samozřejmě použít všude tam, kde chceme návštěvníkům nabídnout vyhledávání a nemáme možnost použít serverové skripty. Daní za to je však složitější editace stránek než v případě „obyčejného“ HTML – musíme „vyprogramovat“ více věcí než obvykle.