Autor Zpráva
Joan
Profil
Pěkný den,
první otázka:
prosím znalé o názor, zda a jak lze můj níže vložený kód zjednodušit, protože drtivá část kódu uprostřed každého "case" se opakuje (zvýraznila jsem). Já jsem šťastná, že jsem došla sama na funkční řešení, ale určitě to půjde elegantněji, ale už žádný můj další pokus nevedl k funkčnímu skriptu.

<style type="text/css">
.uprav1, .uprav2, .uprav3 {display: block; position: absolute; margin-left: 300px; padding: 6px; background-color: #ffa; border: 2px solid green;}
.uprav1 {margin-top: -34em;}
.uprav2 {margin-top: -23em;}
.uprav3 {margin-top: -9em;}
.skryj {display: none;}
</style>  
     </head>
  <body>
  <h3>Zobrazování obrázků z vícero bloků klikáním na jejich náhledy</h3>
<div id="blok1">
<a href="A1.jpg"><img src="A1_th.jpg" width="60" height="60"></a>
<a href="A2.jpg"><img src="A2_th.jpg" width="60" height="60"></a>
</div>
   <div id="tady1"></div>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec pulvinar vulputate orci at ultricies. Etiam in velit eros. Donec a dignissim nisl. Pellentesque venenatis ante at sem lobortis rutrum laoreet purus hendrerit...</p>

<div id="blok2">
<a href="B1.jpg"><img src="B1_th.jpg" width="60" height="60"></a>
<a href="B2.jpg"><img src="B2_th.jpg" width="60" height="60"></a>
<a href="B3.jpg"><img src="B3_th.jpg" width="60" height="60"></a>
<a href="B4.jpg"><img src="B4_th.jpg" width="60" height="60"></a>
</div>
   <div id="tady2"></div>

<p>Sed tempor pellentesque mauris at varius. Suspendisse elit mauris, porttitor in viverra ac, volutpat eget lorem. Ut tempor elementum aliquet. Sed auctor facilisis blandit. Sed sit amet suscipit urna. Fusce ut auctor lorem...</p>

<div id="blok3">
<a href="C1.jpg"><img src="C1_th.jpg" width="60" height="60"></a>
</div>
   <div id="tady3"></div>
  
<script language="JavaScript" type="text/javascript"><!--   
for (var k = 1; k < 4; k++)   //k = pocet bloku na strance, odkud beru nahledy
{ 
var snimek = document.createElement("img");
var kam = document.getElementById("tady"+k);
kam.appendChild(snimek); 
  switch(k)
        {
          case 1:  {var nahled = document.getElementById("blok1").getElementsByTagName("a");
                      for (var n = 0; n < nahled.length; n++)  //n = pocet nahledu v bloku
                      {
                         //IE a Opera vkladaji ctverecek pro imaginarni obrazek
                         snimek.className = "skryj";
                         nahled[n].onclick = function ()
                            {
                            snimek.src = this.href;
                            snimek.className = "uprav1";
                            return false;
                            }
                      } 
                   }    
                   break;  
                   
          case 2:  {var nahled = document.getElementById("blok2").getElementsByTagName("a");
                      for (var n = 0; n < nahled.length; n++)  //n = pocet nahledu v bloku
                      {
                         //IE a Opera vkladaji ctverecek pro imaginarni obrazek
                         snimek.className = "skryj";
                         nahled[n].onclick = function ()
                            {
                            snimek.src = this.href;
                            snimek.className = "uprav2";
                            return false;
                            }                           
                      } 
                   }    
                   break; 
                   
          case 3:  {var nahled = document.getElementById("blok3").getElementsByTagName("a");
                      for (var n = 0; n < nahled.length; n++)  //n = pocet nahledu v bloku
                      {
                         //IE a Opera vkladaji ctverecek pro imaginarni obrazek
                         snimek.className = "skryj";
                         nahled[n].onclick = function ()
                            {
                            snimek.src = this.href;
                            snimek.className = "uprav3";
                            return false;
                            }
                      } 
                   }    
                   break; 
          default: alert("Velký obrázek bohužel\nnelze zobrazit");                            
        }     
                   snimek.onclick = function()   //zavreni velkeho obrazku
                   {
                      snimek.className = "skryj";   
                   }
}           
          
//-->
</script>


Takto to vypadá v reálu. Snaha nahradit číslice 1-3 pomocí "k" jako např. místo "blok1" napsat "blok"+k a udělat univerzální skript nevedla k cíli.

Druhá otázka:
Bude-li jediný obrázek, je zbytečné používat FOR cyklus, že. Níže uvedený kód mi funguje, ale z mně neznámého důvodu nelze použít externí stylování jako v předchozím případě s FOR cyklem a nelze použít variantu typu
var nahled = document.getElementById("blok1").getElementsByTagName("a");

pouze s ID příslušného odkazu (snad proto, že náhled je jen jeden a hledám "elements" tj. množné číslo?). Stejně tak je pro mě problematické přidělení className prvku, který je imaginární (tvořený přes createElement)

kód:
.uprav {display: block; position: absolute; margin-left: 300px; margin-top: -34em; padding: 6px; background-color: #ffa; border: 2px solid green;}
.skryj {display: none;}
img {border: none;}
</style>
<h3>Zvětšení jednoho obrázku z náhledu</h3>
<div id="blok">
<a href="kytka.jpg" id="obr"><img src="kytka_th.jpg" width="60" height="45"></a>
</div>
   <div id="tady"></div>
   
<script language="JavaScript" type="text/javascript"><!--
var snimek = document.createElement("img");
var kam = document.getElementById("tady");
kam.appendChild(snimek); 
var nahled = document.getElementById("obr"); 
//var nahled = document.getElementById("blok").getElementsByTagName("a");   
snimek.style.display = "none";                    
nahled.onclick = function ()
  {
    snimek.src = this.href;
    snimek.style.border = "2px solid green";
    snimek.style.padding =  "6px";
    snimek.style.display = "block";
    //snimek.className = "uprav";
    return false;
  } 
    snimek.onclick = function()   //zavreni velkeho obrazku kliknutím
      {
        snimek.style.display = "none"; 
        //snimek.className = "skryj";  
      }
  
//-->
</script>


Zakomentované řádky způsobí nefunkčnost celého skriptu, naživo zde

Díky moc předem za nástřel úpravy!
Segi_L
Profil
Joan:
Takto to vypadá v reálu. Snaha nahradit číslice 1-3 pomocí "k" jako např. místo "blok1" napsat "blok"+k a udělat univerzální skript nevedla k cíli.
Prečo nie? Vypadá to v poriadku.
switch(k)
        {
          case 1:                   
          case 2:                      
          case 3:  {var nahled = document.getElementById("blok"+k).getElementsByTagName("a");
                      for (var n = 0; n < nahled.length; n++)  //n = pocet nahledu v bloku
                      {
                         //IE a Opera vkladaji ctverecek pro imaginarni obrazek
                         snimek.className = "skryj";
                         nahled[n].onclick = function ()
                            {
                            snimek.src = this.href;
                            snimek.className = "uprav"+k;
                            return false;
                            }
                      } 
                   }    
                   break; 
          default: alert("Velký obrázek bohužel\nnelze zobrazit");                            
        }
Marek88
Profil
Joan:
1)snaha nahradit číslice 1-3 pomocí "k" jako např. místo "blok1" napsat "blok"+k a udělat univerzální skript nevedla k cíli.
Tak by to ale určitě fungovat mělo.
2)Bude-li jediný obrázek, je zbytečné používat FOR cyklus, že.
Ano, ale i přesto je výsledkem pole (o jednom prvku) a proto je potřeba k tomu tak přistupovat. Mělo by fungovat:
var nahled = document.getElementById("blok1").getElementsByTagName("a")[0];
Joan
Profil
Segi_L:
Díky za odpověď.
Prečo nie? Vypadá to v poriadku.
Právěže jen vypadá :-( protože skript sice vybere obrázky ze správného bloku, ale už neví, kde je má zobrazit. Nastavená třída je pro něj očividně neznámá, takže zvětšeninu zobrazí bez jakéhokoliv formátování.
P.S.: Netušila jsem, že položky case mohou být i prázdné, ale úplně stejně skript reaguje, i když doplním do case univerzální proměnnou "k":

switch(k)
        {
            case k: {var nahled = document.getElementById("blok"+k).getElementsByTagName("a");
                      for (var n = 0; n < nahled.length; n++)  //n = pocet nahledu v bloku
                      {  
                         //IE a Opera vkladaji ctverecek pro imaginarni obrazek
                         snimek.className = "skryj";
                         nahled[n].onclick = function ()
                            {
                            snimek.src = this.href;
                            snimek.className = "uprav"+k;
                            return false;
                            }
                      } 
                   }    
                   break; 
                   default: alert("Velký obrázek bohužel\nnelze zobrazit");          


Možno vyzkoušet (obrázek se zobrazí až úplně pod textem).

Pokud úplně vynechám switch a nechám jednoduchou funkci, musím stejně natvrdo dopsat, kde chci velký obrázek otevřít, např.:
snimek.className = "uprav2";

aby se otevřel, kde chci a byl i formátovaný podle nastavené třídy. Takže pokrok žádný...

U samotného obrázku je to velmi zvláštní: Pokud nastavím TŘÍDU na zobrazení
.uprav {display: block; position: absolute; margin-left: 300px; margin-top: -34em; padding: 6px; background-color: #ffa; border: 2px solid green;}
, tak se obrázek neotevře.

Pokud udělám jedinou změnu, a to, že zobrazovací třídě nastavím IDENTIFIKÁTOR na zobrazení
#uprav {display: block; position: absolute; margin-left: 300px; margin-top: -34em; padding: 6px; background-color: #ffa; border: 2px solid green;}
tak se obrázek alespoň ráčí otevřít, ovšem formátování je přebráno od miniatury, nikoli odkazu.
Třída na skrytí ale funguje správně, nechápu to!
Segi_L
Profil
Spomínám si, že raz som tiež riešil niečo podobné a to že všetky priradené funkcie sa vykonávali akoby som klikal na posledný odkaz.
nemohol som priradovat do funcie premennu vo for pretože si stále bralo hodnotu, ktorá bola ako posledná. Tak som pozrel jak som to vlastne vtedy riešil.

řádek 11
snimek.className = "uprav"+k;


prepište na
snimek.className = this.parentElement.id.replace('blok','uprav')

viz odkaz nižšie od _es rieši váš (i moj dávny) problém
_es
Profil
Segi_L:
raz som tiež riešil niečo podobné a to že všetky priradené funkcie sa vykonávali akoby som klikal na posledný odkaz.
nemohol som priradovat do funcie premennu vo for pretože si stále bralo hodnotu, ktorá bola ako posledná.
http://diskuse.jakpsatweb.cz/?action=vthread&forum=8&topic=106539#lexikalni-uzaver
Joan
Profil
_es:
Díky za odkaz. Vyzkoušela jsem aplikovat radu z prvního odkazu, protože se mi zdál nejsrozumitelnější (Zbavení se kontextu (odkazu, provázání…) s proměnnou), ale dostala jsem zvláštní výsledek protože pouze obrázky A2 a B3 se zobrazují tam, kde chci. Já to mám poněkud složitější v tom, že beru malé obrázky místo z jednoho hned ze tří bloků, tudíž potřebuji tři různé odpovídající pozice, kde se mají zobrazovat zvětšeniny, takže bez dvou různých proměnných se neobejdu.

for (var k = 1; k < 4; k++)   //k = pocet bloku na strance, odkud beru nahledy
{ 
var snimek = document.createElement("img");
var kam = document.getElementById("tady"+k);
kam.appendChild(snimek);    
             var nahled = document.getElementById("blok"+k).getElementsByTagName("a");
                      for (var n = 0; n < nahled.length; n++)  //n = pocet nahledu v bloku
                      {  (function()  {
                         var k = n;
                         nahled[n].onclick = function () 
                            {
                            snimek.src = this.href;
                            snimek.className = "uprav"+k;
                            return false;
                            }
                                      }) (); 
                      }                      
                                              
                       snimek.onclick = function()   //zavreni velkeho obrazku
                          {
                       snimek.className = "skryj";   
                          }
}       


Problém dělá umístění zobrazení velkého obrázku (ve skriptu zvýrazněno). Pokud dosadím konkrétní hodnotu (uprav1, uprav2 nebo uprav3), tak se velké obrázky zobrazí - bohužel ze všech bloků v totožném umístění, což není mým záměrem.
Mám prosím ve skriptu nějakou zásadní chybu? Nemyslím syntaktickou, parser mlčí. Děkuji!
_es
Profil
Joan:
Mám prosím ve skriptu nějakou zásadní chybu?
Si to riešila, no nedoriešila.
Ešte musíš vyriešiť premennú snimek, ktorá ti zostala spoločná-zdieľaná pre všetky funkcie priradené do všetkých vlastností onclick.

Nepotrebuješ rôzne funkcie, jednu pre každý onclick, stačí ti jedna - ktorú priradíš všetkým udalostiam onclick, z hodnoty this.id si potom dokážeš zistiť, o ktorý snímok ide.
Joan
Profil
_es:
Ešte musíš vyriešiť premennú snimek, ktorá ti zostala spoločná-zdieľaná pre všetky funkcie priradené do všetkých vlastností onclick.
Ha, nenapadlo mě, že jedna proměnná, která je navíc vlastně virtuálně vytvořená, nemůže "putovat" podle toho, kam ji nasměruji. Asi ten <code>snimek</code> budu muset dát do pole, že.
Segi_L
Profil
Joan:
for (var k = 1; k < 4; k++)   //k = pocet bloku na strance, odkud beru nahledy
{ 
var snimek = document.createElement("img");
var kam = document.getElementById("tady"+k);
kam.appendChild(snimek);    
             var nahled = document.getElementById("blok"+k).getElementsByTagName("a");
                      for (var n = 0; n < nahled.length; n++)  //n = pocet nahledu v bloku
                      {  (function()  {
                         var k2 = k;
                         nahled[n].onclick = function () 
                            {
                            snimek.src = this.href;
                            snimek.className = "uprav"+k2;
                            return false;
                            }
                                      }) (); 
                      }                      
                                              
                       snimek.onclick = function()   //zavreni velkeho obrazku
                          {
                       snimek.className = "skryj";   
                          }
} 
_es
Profil
Segi_L:
Lokálna premenná môže mať taký istý názov ako globálna či globálnejšia. Alebo si chcel naznačiť, že sa má uchovať premenná k z prvého cyklu, miesto premennej n z druhého cyklu? Mne sa to nechcelo toľko študovať, je to trochu neprehľadné.

Joan:
Asi ten <code>snimek</code> budu muset dát do pole, že.
Nie, len presne tak isto, ako si vyriešila premennú n, vyriešiš aj premennú snimek.
Alebo skús porozmýšľať nad priraďovaním len jednej funkcie ([#8]).
Joan
Profil
Segi_L:
Wow, já s prominutím koukám jako jojo - tak to je kouzlo, ono to konečně funguje! Přiznám se bez mučení, že toto by mě v žádném případě nenapadlo. A že můžu k proměnné jen tak přilepit číslici.
Předpokládám, že dvojka je tam proto, že mám bloky 3, takže u jiného počtu bloků tam bude vždy číslice k-1, mám pravdu?
Jinak vřele děkuji, začala jsem tento skript řešit už před vánocemi a bez úspěchu.
_es
Profil
Joan:
No, ale tebe vlastne stačí len jeden element <img>, aj tak používaš len jeden.
Teda by to malo byť:
var snimek = document.createElement("img");
document.body.appendChild(snimek);
snimek.onclick = function()   //zavreni velkeho obrazku
{
  this.className = "skryj";   
};
for (var k = 1; k < 4; k++)   //k = pocet bloku na strance, odkud beru nahledy
{ 
             var nahled = document.getElementById("blok"+k).getElementsByTagName("a");
                      for (var n = 0; n < nahled.length; n++)  //n = pocet nahledu v bloku
                      {  (function()  {
                         var k2 = k;
                         nahled[n].onclick = function () 
                            {
                            snimek.src = this.href;
                            snimek.className = "uprav"+k2;
                            return false;
                            };
                                      }) (); 
                      }                      
                                              

}
Joan
Profil
_es:
Pravda, ušetřím jeden řádek kódu, díky.
Prapůvodně jsem vycházela z tohoto zobrazování (a skriptu) a postupně ho upravovala podle své představy.

presne tak isto, ako si vyriešila premennú n, vyriešiš aj premennú snimek
Pro obě proměnné "k" i "n" (neumím zobrazit kód zeleně tak, aby byl přímo v textu a ne na samostatném očíslovaném řádku) mám FOR cyklus, akorát u proměnné "n" mám uvnitř funkci a u "k" nemám -toto máš na mysli?

Pokusem jsem s údivem zjistila, že vůbec nemusí být
var k2 = k;

protože když si vymyslím úplně nový název proměnné, tak skript šlape stále stejně, např.:
var ahoj = k;

a potom
snimek.className = "uprav" +ahoj;

Jenom mi vrtá hlavou, proč skript potřebuje ještě třetí proměnnou a nestačí mu dané "k".
Jinak mockrát děkuji za trpělivost, dneska jsme se pohnula o míle dál :-)
Segi_L
Profil
Joan:
Předpokládám, že dvojka je tam proto, že mám bloky 3, takže u jiného počtu bloků tam bude vždy číslice k-1, mám pravdu?

Ta dvojka je tam preto, aby sa uložila globálna premenná do lokálnej je vlastne jedno ako ju nazveš klidne var puvodni_k = k. keby si mala iný počet bloku, tak na kode sa nemusí nič meniť.
keby tam bolo var k = k; tak by to nefungovalo(vyskúšané), pretože nová premenná k by sa vobec nevytvorila, pretože už je raz vytvorená vyššie. Je to asi preto, lebo funciu vyváraš za behu. Fak neviem. Ja až tak javaScriptu nerozumiem. Pričuchol som k nemu asi pred rokom, keď som programoval administraci pre eshop, kde som práve riešil podobný problém viz vyššie.
Joan
Profil
Segi_L:
Pričuchol som k nemu asi pred rokom
Klobouk dolů! Já s ním "zápasím" (jen z nadšení, školní roky mám dávno za horami) o něco déle. Ale pomohl jsi mi velmi.
Teď ještě jak poznat, kdy že je potřeba globální proměnnou ukládat do lokální...
_es
Profil
Joan:
toto máš na mysli?
Nie, vtedy som sa ešte málo porozmýšľal nad kódom a neuvedomil si, že stačí len jeden <img>.
Išlo o to, že premenná snimek je tiež zdieľaná medzi tými funkciami a aj keď si vytvárala 4 objekty obrázka, tak sa potom následne používal len ten posledný.

Segi_L:
keby tam bolo var k = k; tak by to nefungovalo(vyskúšané), pretože nová premenná k by sa vobec nevytvorila, pretože už je raz vytvorená vyššie.
Nie, to je nesprávne vysvetlenie.
Lokálna premenná k existuje už pred tým, ako interpret spustí príkaz var k=k;, no jej hodnota je undefined, teda bude po príkaze v lokálnej premennej hodnota undefined.
No príkaz var k=n;, kde n je globálnejšia premenná a neexistuje lokálna premenná s názvom n, funguje podľa očakávania a vôbec nevadí, ak existuje aj globálnejšia premenná k.
Joan
Profil
Když jsem u původní varianty
snimek.className = "uprav"+k

vložila za to
alert(snimek.className);

tak to vyplivlo "uprav4" - jak to? Vždyť ve FOR cyklu mám k< 4 a ne k<= 4!
_es
Profil
Joan:
Vždyť ve FOR cyklu mám k< 4 a ne k<= 4!
Ale výsledná hodnota premennej k po skončení cyklu je 4.
Na konci poslednej iterácie sa k nastaví na 4 a v podmienke cyklu sa zistí, že neplatí k<4 a cyklus skončí.
Witiko
Profil
Ono by úplně místo tvorby proměnné k2 stačilo zavolat danou anonymní funkci s argumentem, viz closure - uzávěra. Tak dojdeme k vytvoření lokální proměnné o stejné hodnotě (pokud bereme argument funkce jako lokální proměnnou) i stejném názvu.
doDeseti:
  for(var index = 0; index <= 10; index++) {
    (function(index) {
      setTimeout(function() {
        alert(index); // Po jedné sekundě navrátí pomocí metody alert index s takovou hodnotou, jakou měl v daném bodě cyklu.
      }, 1000);
    })(index);
  }
_es
Profil
Witiko:
Ono by úplně místo tvorby proměnné k2 stačilo zavolat danou anonymní funkci s argumentem
Čo je vlastne to isté, len v inom obale. Namiesto lokálnej premennej k2 sa použije lokálna premenná index, ktorá svojim názvom „prekryje“ globálnu premennú index.
Witiko
Profil
_es:
Jj, ale přijde mi to hezší. :-) Všeobecně mám radši, když člověk nemusí zbytečně tvořit nové názvy proměnných pro stejnou věc.
_es
Profil
Witiko:
ale přijde mi to hezší.
No ale zase môže byť náročnejšie sa zorientovať, o aký index sa jedná, či o ten globálny alebo o ten lokálny. Preto by sa mohla premenná/argument funkcie nazvať inak.
Witiko
Profil
_es:
To ano, nicméně tento případ nepředpokládá využívání dané proměnné mimo vytvořený anonymní scope.
Joan
Profil
Tak mám všechno pohromadě a funguje mi to zaplaťpánbu jak jsem chtěla. Už i u jednotlivých obrázků #4, kde jsem měla nesmyslně nastavenou jednu deklaraci, která mi obrázek zobrazovala mimo zorné pole, proto se mi mylně zdálo, že se nezobrazuje vůbec.

Váhám ještě nad tímto:
když v každém bloku bude několik obrázků, tak samozřejmě použiji FOR cyklus na jejich procházení jako tady. Co když ale mám jeden obrázek nahoře na stránce, druhý uprostřed a třetí na konci stránky a každý chci zobrazovat ve zvětšení vedle miniatury? Nejspíš taky mám procházet pole byť o jediném prvku než použít pro každý obrázek (níže uvedený) extra skript, že?

<div id="blok">
<a href="kytka.jpg"><img src="kytka_th.jpg" width="60" height="45"></a>
</div>
   <div id="tady"></div>
   
<script language="JavaScript" type="text/javascript"><!--
var snimek = document.createElement("img");
var kam = document.getElementById("tady");
kam.appendChild(snimek); 
snimek.className = "skryj";
var nahled = document.getElementById("blok").getElementsByTagName("a")[0];                                   
nahled.onclick = function ()
  {
    snimek.src = this.href;
    snimek.className = "uprav";
    return false;
  } 
    snimek.onclick = function()   //zavreni velkeho obrazku kliknutím
      {
        snimek.className = "skryj";  
      }  
//-->
</script>
Segi_L
Profil
Joan:
Nejspíš taky mám procházet pole byť o jediném prvku
Myslím že to bude najlepšie. Je celkom jedno či bude prechádzať for cyklom len jeden krát, alebo tu vyberete prvý záznam ktorý vám vráti 11. riadok.

Takže zbytočne písať extra funkciu, pre jeden obrázok.
_es
Profil
Joan:
Teoreticky ti na všetko stačí jedna funkcia podobne ako tu.
V tej by si z premennej target zistila, na aký element sa kliklo, napríklad target.id je id prvku, target.className trieda css a pod.
Podľa toho by si rozvetvila reakciu na kliknutie.
Joan
Profil
_es:
Teoreticky ti na všetko stačí jedna funkcia podobne ako tu.
Tak to už je na mě poněkud složitější, ale pokusím se přebrat si to.
Zatím moc děkuji vám oběma, pěkný víkend!

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