Autor Zpráva
JS_blb
Profil *
Zdravím zdejší znalce! V JS jsem totálně blbý, tak prosím o radu, třeba bude snadná?

Na skrývání menu v mobilním rozlišení používám http://jecas.cz/prepinani-trid - funguje skvěle, jen mi chybí funkcionalita, aby při kliknutí mimo menu se dotyčné zavřelo?

Našel jsem jedno více řešení, ale většinu se mi nedaří jako totálnímu JS laikovi implementovat, navíc tam nechci knihovny JQuery (nebo jak se to...). Jediné, co je dostatečně prosté, aby mi to fungovalo je tohle:

<script type="text/javascript">
  (function () {
    "use strict";
    var hiddenItems = document.getElementsByClassName('hidden'), hidden;
    document.addEventListener('click', function (e) {
        for (var i = 0; hidden = hiddenItems[i]; i++) {
            if (!hidden.contains(e.target) && hidden.style.display != 'none')
                hidden.style.display = 'none';
        }
        if (e.target.getAttribute('data-toggle')) {
            var toggle = document.querySelector(e.target.getAttribute('data-toggle'));
            toggle.style.display = toggle.style.display == 'none' ? 'block' : 'none';
        }
    }, false);
})();
</script>

<a href="javascript:void(0)" data-toggle="#hidden1">Toggle Hidden Div</a>
<div class="hidden" id="hidden1" style="display: none;" data-hidden="true">This content is normally hidden</div>

Jenomže to zase neskryje menu, když kliknu přímo na tlačítko/odkaz, kterým jsem ho vyvolal, což je trochu matoucí, dle mého...

RESUMÉ: nešla by obě řešení zkombinovat nějak tak, aby výsledkem bylo: při kliknutí na tlačítko se zobrazí menu, při opětovném kliknutí na tlačítko, či kamkoliv jinam mimo, se menu skryje?

Vypadá to primitivně, ale pro mě je to neřešitelný koán :-)
Keeehi
Profil
JS_blb:
Jako základ dobrý, i když pro tvůj problém asi zbytečně složité. Nicméně těžko ti můžeme poradit jak to upravit, když nevíme jak vypadá tvoje stránka. Chtělo by to živou ukázku.
JS_blb
Profil *
Keeehi:
No ale já to mám prostě jak to leží a běží - tak tedy zde: Živá ukázka (místo toho "This content is normally hidden" mám pochopitelně to menu...)

Vše - jak vidno - normálně funguje, jediné, co bych navíc potřeboval, aby se to skrylo i když podruhé kliknu na to tlačítko... A jestli to může být i jednodužší kód? No tak super, sem s ním!
Keeehi
Profil
JS_blb:
Jako pokud ti jde konkrétně o tuhle ukázku tak se do dá jednoduše zapsat takto. Ovšem nejsem si jistý, že když to vezmeš a přímo to zkopíruješ do nějakého projektu, tak to bude fungovat. Je to dělané přímo na míru tomuto jednoduchému příkladu.

Těch možností implementace je samozřejmě spousta. Tuto jsem zvolil jelikož by z ní mělo být celkem jednoduše vidět co se tam kde dělá.
JS_blb
Profil *
Keeehi:
Vyzkouším zejtra, ale vypadá to jak jsem potřeboval! Tisíceré díky!!!
("Projekt" bude na flash/CD, takže proto jej nemám online.)
breeta
Profil
Co tohle, nestačí?

Živá ukázka

 const hidden  = document.querySelector('.hidden') 
      
    document.addEventListener('click', (e)=> { 
         if(hidden.style.display === 'none' && e.target.id === 'menu') {
               hidden.style.display = 'block' 
         } else {
               hidden.style.display = 'none' 
         }  
   })
Keeehi
Profil
breeta:
Pokud se skrývá jen jeden element tak určitě. Pro více elementů by se tam musel přidat cyklus na jejich skrytí. Což je ale víceméně drobnost.
breeta
Profil
Keeehi:
Ano dát querySelectorAll a forEach ....
JS_blb
Profil *
breeta, Keeehi:

Ještě jednou upřímný hlubosklon a díky oběma! Zatím mi fungují oba skripty všude kde jsem stačil vyzkoušet, jen jsem si prožil horkou chvíli, protože jsem je nejdřív umísťoval do hlavičky - a nic!

Ony musí být opravdu umístěny v kódu až ZA html toho tlačítka? Protože jedině tak mi to fachčí...

Jako amatér jsem se jakž takž naučil HTML a CSS, ale u toho JS troskotám, to je pro mě španělská vesnice a svévolný shluk písmen! (Svůj pseudonym myslím upřímně :) )
Firibix
Profil
Reakce na JS_blba:
Ony musí být opravdu umístěny v kódu až ZA html toho tlačítka?
JavaScript se ve webové stránce začne vykonávat ihned, jakmile na něj prohlížeč ve zdrojovém kódu narazí. Pokud ve skriptu chceme pracovat s nějakým elementem (třeba začít naslouchat na událost click nějakého tlačítka, nebo si do proměnné uložit odkaz na elementy se třídou hidden), tak skript musíme umístit až za něj. Jinak v době vykonávání skriptu ten element ještě nebude existovat a nastane chyba.
JS_blb
Profil *
Firibix:
Díky, zapisuju za uši - aspoň takovéhle obecnosti jsem schopen rozumět!


breeta:
Ještě jsem teď zjistil, že ten tvůj kratší kód nefunguje v IE 10... (kolegův jo)
Keeehi
Profil
Ovšem dá se to udělat i tak, aby ten javascript mohl být na stránce kdekoliv. Stačí mu spuštění "odložit" až do doby kdy bude načtení celá stránka. Jak to udělat? Stejně jako je třeba událost click na tom buttonu, existuje událost ready nad samotnou stránkou. Ta se zavolá až když je stránka celá načtení. V obsluze té události se klidně můžeš odkazovat na jakýkoli prvek na stránce, jelikož už je v té chvíli vytvořen. Zní to sice složitě ale je to vlastně úplně triviální. Prakticky stačí celý kód jen obalit do funkce. Takový kód pak může být umístěn úplně kdekoli protože to tělo té funkce se začne vykonávat až ve správný čas.

document.addEventListener('ready', (e)=> {
    const hidden  = document.querySelector('.hidden') 
      
    document.addEventListener('click', (e)=> { 
         if(hidden.style.display === 'none' && e.target.id === 'menu') {
               hidden.style.display = 'block' 
         } else {
               hidden.style.display = 'none' 
         }  
   })
})

Ještě jsem teď zjistil, že ten tvůj kratší kód nefunguje v IE 10... (kolegův jo)
Ono totiž IE10 prostě nezná některé ty nové vymoženosti co tam Firibix použil. Pokud je potřeba zajistit funkčnost i v takto starém prohlížeči je to samozřejmě možné. Stačí použít ten starší typ zápisu, který sice není tak sexy ale funguje všude. Místo const se použije var, místo (e)=> se použije function (e). Pak možná bude ještě problém s querySelector. Tam se zase dá použít getElementsByClassName(".hidden")[0]
Po takové úpravě by to mohlo fungovat i v IE.
JS_blb
Profil *
Jo, díky - já se budu muset do toho JS taky zakousnout a naučit se to, ale to jde stejně nejlíp zkoumáním těch příkladů. Ještě určitě budu mít později nějaký dotaz, to asi v jiném vlákně, ale když jsme u toho IE10:

Zkoušel jsem mnater.github.io/Hyphenator a funguje i tam, ale na začátku každé stránky (pouze v IE) dělá podivný artefakt tečku a jakoby znak "nepísmenka" tj. malý obdelníček: - někde jen ten obdelníček.

No a tam už na to absolutně nemám šanci přijít! Asi za to taký může nějaká "vymoženost"... :-) Kdybys tušil, tak dej vědět, díky.
JS_blb
Profil *
Keeehi:
Ještě detail: potřebuju, aby ten skript fungoval jen při menší šířce pro mobil určené v CSS @media screen and (max-width: 600px), jinak mi při normální šířce způsobí, že všechno je naprosto OK, ale při kliknutí do stránky menu zmizí...

Toho jsem si hned v tom nadšení nevšiml. Dá se to určit přímo v tom scriptu? (Předpokládám, že pomocí CSS vypnout nejde.)

Vyřešil jsem to příšerně prasácky, že tam mám to menu dvakrát atd., ovšem to je hrůza! :)

Jinak běhá fakt krásně!
Keeehi
Profil
JS_blb:
Kdybys tušil, tak dej vědět, díky.
BOM?

Dá se to určit přímo v tom scriptu?
Udělal bych to tak, že bych v JavaScriptu kontroloval nějakou vlastnost která se tím media query mění. Tím zjistíš, jestli se ten styl aplikoval nebo ne. A podle toho se zařídíš.
Ale zase, bez kódu ti konkrétněji poradit nemůžu.

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:

0