Autor Zpráva
hypot
Profil
Zdravím, pokud někdo bude tak laskav, chtěl bych vysvětlit některé věci, kterým nerozumím na skriptu, který je na stránce www.the-art-of-web.com/javascript/search-highlight (nadpis č. 3).
Z větší části ten skript chápu, ale nerozumím (mimo jiné) tomuto:
1) skript (funkce this.hiliteWords = function(node) {... ) prohledá jeden po druhém textové uzly v zadané části stránky a nalezená slova shodující se ze zadáním vloží do nově vytvořeného prvku EM; skript zvýrazní všechny výskyty nalezeného slova v rámci jednoho textového uzlu, nikoli jen první výskyt, ale já to opakované hledání v tom skriptu nikde nevidím (čekal bych nějakou smyčku, ta tam však není) - čili můj první dotaz je, kde se v něm uvádí, aby se daný textový uzel prohledával tak dlouho, dokud nejsou nalezeny všechny výskyty zadaného slova v něm (než se přejde na prohledávání dalšího textového uzlu);
2) je-li nalezeno slovo odpovídající zadání, textový uzel je rozdělen na dva metodou splitText, která má jako parametr indexovou pozici znaku, kterým má začínat druhá oddělená část; já bych tomu rozuměl, kdyby v tomto skriptu bylo var after = node.splitText(nv.indexOf(regs[0])), jenž ono tam místo toho je splitText(regs.index) - tomu já ovšem nerozumím ze dvou důvodů: jednak nevím, co znamená slovo index (vypadá to jako nějaká vlastnost pole, ale já jsem žádnou takovou vlastnost nenašel), jednak v proměnné regs je pole (s jednou položkou) a já nevím, co to má společného s polohou znaku v řetězci.
Děkuji za vysvětlení.
hypot
Profil
Tak jsem dále hloubal nad druhou částí dotazu a ačkoli jsem měl částečně úspěch, šťourání v tom mě ještě víc zmátlo.
Úspěch jsem měl v tom, že se mi konečně podařilo najít, co je ono index za jménem pole. Podle www.w3resource.com/javascript/object-property-method/array-index.php jde o vlastnost pole, která udává polohu nalezené shody s regulárním výrazem v textovém řetězci, a byla prý do Javascriptu přidána ve verzi 1.2. Nevím, nakolik je uvedený zdroj autoritativní, na Mozilla Developer Network (kde mně připadá, že je všechno) o existenci takové vlastnosti není zmínka. Kdo ví tedy, zda nebyla zase z Javascriptu odebrána (prohlížeče ji nicméně podporují). Každopádně jsem se pokusil o náhradu této polozáhadné vlastnosti metodou (řetězce) indexOf(), která přece také vrací polohu znaku v rámci řetězce. To jsem se ovšem se zlou potázal, protože jsem začal dostávat neočekávané výsledky a naprosto nemůžu přijít na to, proč. Pokusím se názorně (doufám) ukázat potíže, na které jsem narazil:

Skript odkazovaný v předchozím příspěvku jsem pro usnadnění zjednodušil na nezbytné minimum:
var rVyraz = /\bad/i; // pro zkušební potřebu
/* oblast, v níž se bude vyhledávat: */
var node = document.getElementById("text");
if (node.hasChildNodes) {
    /* jednotlivé odstavce: */
    var deti = node.childNodes;
    for (var cy = 0; cy < deti.length; cy++) {
    /* pokud odstavce obsahují text: */
    if (deti[cy].firstChild && deti[cy].firstChild.nodeType == 3) {
            /* jednotlivé textové uzly daného odstavce: */
            var textuzly = deti[cy].childNodes;
            for (var cu = 0; cu < textuzly.length; cu++) {
                /* pokud je v textovém uzlu shoda s regulárním výrazem: */
                if (rVyraz.test(textuzly[cu].nodeValue)) {
                    var nmark = rVyraz.exec(textuzly[cu].nodeValue);
                    var mark = document.createElement("mark");
                    mark.appendChild(document.createTextNode(nmark[0]));
                    /* rozdělení textového uzlu v místě nalezené shody s regulárním výrazem: */
                    var za = textuzly[cu].splitText(nmark.index); // NEBO var za = textuzly[cu].splitText(textuzly[cu].nodeValue.indexOf(nmark[0]))
                    /* oddělení hledaného výrazu od zbytku textu, aby se ve výsledku neopakoval dvakrát po sobě: */
                    za.nodeValue = za.nodeValue.substring(nmark[0].length);
                    /* vložení nalezené shody mezi dvě části rozděleného textového uzlu: */
                    textuzly[cu].parentNode.insertBefore(mark, za)
                }
            }
        }
        }
    }
Skript je založen na předpokladu, že dokument (jeho relevantní část) bude mít vždy podobu
<div id="text">
<p>Nějaký text.</p>
<p>Nějaký další text.</p>
</div>
Tento skript jsem zkoušel na textu Et solebas suavius esse, canturire belle deverbia, adicere melicam. — Iam, inquit ille, quadrigae meae decucurrerunt, ex quo podagricus factus sum. Alioquin cum essem adulescentulus, cantando paene tisicus factus sum. a chtěl jsem v něm zvýraznit skupinu znaků ad (proto ten regulární výraz má takovou podobu, jakou má).
O co mi stále jde, je parametr metody splitText na 19. řádku skriptu. Vzhledem k účelu této metody jsem se domníval, že budu moct za její parametr dosadit mně srozumitelnější textuzly[cu].nodeValue.indexOf(nmark[0]), což jsem i k příslušnému řádku skriptu napsal jako poznámku. Jenže když jsem skript s takto mně srozumitelným parametrem spustil na uvedeném textu, zvýraznil nejen skupinu ad ve slově adicere a ve slově adulescentulus, ale oproti očekávání i ve slově quadrigae, což je v rozporu se zadaným regulárním výrazem /\bad/i na začátku skriptu. Podobně když zadám regulární výraz /\Bad\B/ a ponechám mnou vložený parametr metody splitText, zvýrazní se sice skupina ad ve slově quadrigae (má být), ale i ve slově adicere (nemá být). Když ponechám v parametru metody splitText ono zvláštní nmark.index, výsledkem jsou správně zvýrazněné výskyty skupiny ad zcela ve shodě se zadanými regulárními výrazy. Ale proč ten rozdíl?
Jestliže najdu v prohledávaném řetězci shodu s regulárním výrazem pomocí metody exec (15. řádek skriptu), vytvoří se pole nmark s jednou položkou, podřetězcem odpovídajícím nalezené shodě. Tato položka má v poli index 0. Budu-li chtít najít její polohu v řetězci, použiju metodu indexOf(); prohledávat budu textový uzel, s nímž zrovna skript pracuje, což je textuzly[cu].nodeValue, a metodě jako parametr zadám hledaný podřetězec, což je první (a jediná) položka pole nmark. Takže dohromady to bude právě textuzly[cu].nodeValue.indexOf(nmark[0]). To vypadá logicky a nevidím v tom nikde chybu. Když skript spustím s regulárním výrazem /\bad/ na výše uvedeném textu, při prvním průběhu smyčky, která začíná na řádku 14, vrátí indexOf() po nalezení shody hodnotu 51, což odpovídá znaku a na začátku slova adicere a je to v pořádku. Poté, co skupina ad tohoto slova je vyňata z textového uzlu a za ní vznikne nový (druhý) textový uzel, proběhne podruhé zmíněná smyčka a metoda indexOf() nyní vrátí hodnotu 37, což odpovídá znaku a ve slově quadrigae, a to ovšem v pořádku není. Jelikož se hledá výskyt podřetězce, který je první položkou pole nmark, vypadá to, že do tohoto pole se vložila skupina znaků ad slova quadrigae. Jenže jak se tam dostala, když neodpovídá regulárnímu výrazu? Nicméně ona tam přece jen být nemusí. Jestliže totiž použiju na 19. řádku splitText(nmark.index), bude mít při druhém průběhu smyčky metoda splitText hodnotu 114, což odpovídá prvnímu znaku slova adulescentulus, takže skupina ad ve slově quadrigae se ve shodě s regulárním výrazem ignorovala a teď to vypadá, že v poli nmark přece jen nebyla. Kde dělá soudruh z NDR chybu?

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: