Autor Zpráva
dalik
Profil
Zdravím vespolek,
potřeboval bych poradit, jak porovnám hash za adresou s ID od určitého elementu a následně mu přiřadil aktivní třídu, když budou shodné.

Napadlo mě to udělat takto: http://kod.djpw.cz/ifgb ale nefunguje to.
Po kliknutí na odkaz se má příslušnému divu, přiřadit aktivní třída.
Joker
Profil
Jednak ten hash je i s mřížkou na začátku, před porovnáním ID je potřeba ji zahodit.

Jednak k nalezení elementu s určitým ID není potřeba procházet dokument, když přímo JS má funkci document.getElementById.

Tohle mi funguje:
Odkaz (kód)

Poznámka: Ale nemění se to po kliknutí na odkaz, protože to nevyvolá nové načtení stránky. Musí se ještě obnovit stránka. Aby to fungovalo i po kliknutí na odkaz, bylo by nutné po kliknutí na odkaz volat tu funkci setActive.
dalik
Profil
Zkusil jsem to teda volat po kliknutí, ale nefunguje to správně. Můžeš mrknout co mám špatně? http://kod.djpw.cz/ufgb
Joker
Profil
Aha.
Tam je problém v tom, že se nejdřív zavolá ta funkce, která ještě přečte starý hash, a teprve potom se následuje odkaz a nastaví nový hash.

Takže by to bylo potřeba navěsit na událost změny hashe, která pokud vím neexistuje a dělá se to periodickým kontrolováním a porovnáváním proti předchozí hodnotě. Možná by fungovalo nastavit nějaký timeout.

Ale pro ty odkazy by nejjednodušší bylo při kliknutí na odkaz nekontrolovat hash, ale přímo nastavovat jako aktivní ten prvek, na který odkaz vede.
dalik
Profil
Joker:
Ale pro ty odkazy by nejjednodušší bylo při kliknutí na odkaz nekontrolovat hash, ale přímo nastavovat jako aktivní ten prvek, na který odkaz vede.
O tohle se něják snažím, ale jediný co tak trochu znám je jquery, proto jsem to zkoušel přes hash.
Mohl bys mi něják aspoň poradit, jak na to?
Joker
Profil
dalik:
No tak udělat to „ručně“ u odkazů by bylo snadné.
Upravíme si setActive, aby element brala zvenku:
setActive = function(elmid) {
    var el = document.getElementById(elmid);
    if(el) el.className += " active";
}

Pak to úvodní nastavení bude: setActive(location.hash.substring(1));

No a odkaz bude: <a href="#id1" onclick="setActive('id1')">fds</a>

Potíž je, že by takhle musely být modifikované všechny ty odkazy.
Tohle by mělo projít odkazy na stránce, zjistit, které začínají mřížkou a těm ten onclick udělat automaticky:
    var links = document.getElementsByTagName("a");
    for(var i = 0; i < links.length; i++) {
        // Pozn.: Je potřeba getAttribute("href"), protože links[i].href je plná adresa
        if(links[i].getAttribute("href").substring(0,1) === "#") {
            links[i].addEventListener("click", function() {
                setActive(this.getAttribute("href").substring(1));
            });
        }
    }
dalik
Profil
Super! Děkuji, i za vysvětlení.
_es
Profil
Joker:
Na odkazy existuje aj document.links a addEventListener nebude fungovať v IE8 a starších, stačí obyčajné onclick.
Joker
Profil
_es:
stačí obyčajné onclick.
Pokud ovšem ten odkaz nebude už mít obsluhu onclick.

Ještě poznámka, u té kontroly href by možná bylo fajn vyloučit odkazy tvořené jenom mřížkou, pokud takový formát odkazů stránka používá ke spouštění JS funkcí (když se má nějaký JS spustit kliknutím na něco, hodně stránek k tomu používá <a href="#" onclick=…>).
dalik
Profil
Ještě se chci zeptat, jak udělám, aby se po kliknutí dalšího odkazu smazala původní třída active.
Chamurappi
Profil
Reaguji na Jokera:
Potíž je, že by takhle musely být modifikované všechny ty odkazy.
Nebo stačí sledovat window.onhashchange… podporováno od Exploreru 8.
Devítka a ostatní prohlížeče znají i pseudotřídu :target, která dělá nejspíš totéž, co chce dalik doskriptovat.

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: