Autor Zpráva
Herbolt
Profil *
Mám nějakou html stránku s hodně odstavci s různými IDčky a pomocí JS bych potřeboval odladit funkci která by zařídila, že po kliknutím myší nad jakýmkoliv odstavcem by to vyhodilo třeba alert s tímto obsahem: "Klepnul jsi na odstavec s ID a1" (po kliknutí nad <p id="a1">...</p>)

Pomůže někdo lajkovi :). Díky
weroro
Profil
<p id="a1" onclick="alert('Klepnul jsi na odstavec s ID ' + this.id);"></p>
Herbolt
Profil *
Dík.... to mne napadlo, ALE zapomněl jsem dodat že to nechci mít inline zápisem, ale pokud možno nadefinovat to nějak co nejúsporněji do hlavního JS kódu... to neumím.
Herbolt
Profil *
Hrál jsem si a snad toto vypadá funkčně, akorát nevím jestli je to dobré pro všechny možné prohlížeče, pokud ne! Dejte vědět něco lepšího, díky:


 var ps = document.getElementsByTagName("p");
 for (var i = 0; i <= ps.length; i += 1) {
    ps[i].onclick = function(e) {
        alert(this.id);
    };
 }
CZghost
Profil
Herbolt:
ale pokud možno nadefinovat to nějak co nejúsporněji do hlavního JS kódu...
Nejúsporněji to dovede jQuery, ale kvůli vyskakovacímu okénku bych to nedoporučil. jQuery se používá spíše na pěkné efekty, které by jinak zabraly spoustu kódu. To spíš nějak takhle:
<script type="text/javascript">
odstavce         = document.getElementsByTagName('p');   // získám všechny odstavce
posledniOdstavec = odstavce.lenght - 1;                  // číslování od nuly
odstavec         = null;                                 // počáteční inicializace proměnné

for(i = 0; i <= posledniOdstavec; i++) { // cyklus s uzavřeným počtem průběhů:
    // začíná na nule, opakuje se, dokud platí podmínka, po každém průběhu se řídící proměnná zvýší o jednu
    odstavec         = odstavce[i];                      // načtu si daný odstavec do inicializované proměnné
    odstavec.onclick = function(e) {
        alert("Klepnul jsi na odstavec s ID " + this.id); // přiřadím danému odstavci událost onclick
    };
} // konec cyklu
</script>

Je to dost jednoduché, mělo by to fungovat, vyzkoušej si to.



Tak jsem přišel s křížkem po funuse :D To i <= ps.length bych spíš změnil na toto: i < ps.lenght (případně menší nebo rovno to mínus jedna, smazání rovnítka je jednodušší a funguje totožně).



Tak jsem si trošku hrál s živou ukázkou, tady je výsledek↓ :)
Zdrojový kód: http://kod.djpw.cz/hddb
Samotná živá ukázka: http://kod.djpw.cz/hddb-

Funguje to perfektně :)

EDIT: Předělal jsem událost onclick na lepší zápis pomocí funkce.
joe
Profil
Nejúsporněji to uděláš tímto:
$("body").on("click", "p", function() {
    var paragraph = this;
    alert(paragraph.id);
});

(to je pro jQuery), bez něj to lze samozřejmě také.
CZghost
Profil
joe:
bez něj to lze samozřejmě také.
Však to už jsem taky napsal :-) jQuery je na tohle zbytečný, pokud tam nechceš nějaké ty efekty, takže lepší to je čistým JS ;-)
1Pupik1989
Profil
A co třeba takto?

document.onclick = function(e){
  e = e || event;
  var el = e.srcElement || e.target;

  if(el.nodeName === 'P'){
    alert(el.id);
  }
};

A ušetřím 100 kB. :)
CZghost
Profil
1Pupik1989:
To nebude fungovat všude. Tenhle kód nebude fungovat pouze uživatelům s vypnutým JS:
<script type="text/javascript">
odstavce         = document.getElementsByTagName('p');
posledniOdstavec = odstavce.lenght - 1;
odstavec         = null;
 
for(i = 0; i <= posledniOdstavec; i++) {
    odstavec         = odstavce[i];
    odstavec.onclick = function(e) {
        alert("Klepnul jsi na odstavec s ID " + this.id);
    };
}
</script>

Je to obyčejné přiřazování a cyklus, fungovat bude ve všech moderních prohlížečích, takové vykopávky typu IE 3 nebo Netscape už zdarbohu vymizely :-)
Už se opakuju, tak jsem alespoň vymazal poznámky. Prosím případné moderátory, aby tento komentář nemazali :-)
joe
Profil
CZghost:
To nebude fungovat všude
Bude to fungovat.
Je zbytečné iterovat a prohledávat všechny odstavce, stačí nastavit jednu událost, místo N událostí.

1Pupik1989:
A co třeba takto?
A ušetřím 100 kB. :)
To je prakticky to samé, co jsem napsal. Tvůj kousek kódu je ale problematický v tom, že nastavuje "natvrdo" onclick na dokument, takže někde v jiném souboru mže být přepsán.
CZghost
Profil
joe:
Je zbytečné iterovat a prohledávat všechny odstavce, stačí nastavit jednu událost, místo N událostí.
Stejně jako je zbytečné vypisovat hlášku při kliknutí na odstavec. Ano, jde to více způsoby, všechny mají své pro a proti. Tvůj kód má problém v použití obsáhlé knihovny, která je taktéž na toto zbytečná. Kód 1Pupika1989 má problém v nastavení události onclick na celý dokument, nehledě na to, že používá rohodovací operátory, navíc ne moc šikovně (rozhodovací operátory patří do podmínek). Můj kód cyklem přiřazuje každému odstavci událost onclick, což je nejméně problematické, avšak problém poté nastává, když je na stránce třeba padesát takových odstavců, kód to prostě maloučko zpomalí. Herbolt chtěl asi maličko experimentovat, je jasné, že toto se nedá na regulérních stránkách využít, protože čtenáře to ruší. Dejme tomu, že omylem někam klikne a vyskočí na něj okénko s ID odstavce. Určitě se lekne a stránku rychle zavře, takže tímhle by spíš návštěvníky odehnal. Je ale dobré vědět, že to jde a funguje to. Alespoň na experimenty.
joe
Profil
CZghost:
Tvůj kód má problém v použití obsáhlé knihovny, která je taktéž na toto zbytečná.
Můj kód je jen ukázka toho, jakým způsobem to lze udělat. Implementaci a využití nebo nevyužití knihovny je na každém - důležité z kódu tedy je - aplikovat pouze jednu událost a ne N událostí.

Kód 1Pupika1989 má problém v nastavení události onclick na celý dokument
A kde vidíš problém?

používá rohodovací operátory, navíc ne moc šikovně (rozhodovací operátory patří do podmínek)
Používá logické operátory a naprosto v pořádku.

Můj kód cyklem přiřazuje každému odstavci událost onclick, což je nejméně problematické
Proč si myslíš, že to je nejméně problematické?

problém poté nastává, když je na stránce třeba padesát takových odstavců
Ani zde nevidím žádný problém, nejsi schopen rozeznat pár mikro sekund.

Problém tvého kódu je, že zbytečně duplikuje jednu a tu samou funkci tolikrát, kolikrát je ve stránce odstavec. Další nevýhodu má, pokud se změní DOM (například AJAXem) přidáním dalších odstavců - ty budeš muset znovu nastavit události na nové odstavce.
1Pupik1989
Profil
CZghost:
Takže si to shrňme. Bude na stránce 50 paragrafů. Tvůj kód tedy vytvoří 50 anonymních funkcí. Co se stane, když vytvořím v javascriptu nový paragraf a přidám ho do stránky? Nic. Čili by jsi musel upravit všechny metody které manipulují s element (insertBefore, appendChild atd.)

Já bych to zkusil ještě jinak, když si někdo teda není jistý, jestli funkci přepisuje. :)

function onclickParagraph(e){
  e = e || event;
  var el = e.srcElement || e.target;
  
  if(el.nodeName === 'P'){
    alert(el.id);
  }
};

var addEvent;

if(addEvent = document.addEventListener){
  addEvent('click',onclickParagraph,false);   
}else if(addEvent = document.attachEvent){
  addEvent('onclick',onclickParagraph); 

nehledě na to, že používá rohodovací operátory, navíc ne moc šikovně (rozhodovací operátory patří do podmínek)

Myslíš e = e || event;?
To je ekvivalent e = e ? e : event;

Takže to podmínka je.

Čili pokud první neprojde, tak platí druhé. Nevidím v tom sebemenší problém.
CZghost
Profil
1Pupik1989, joe:
A proč to tu vůbec řešíme? Je to blbost, ale funguje to. To je to hlavní, že to funguje. Asi zlomek lidí má potřebu při kliknutí na odstavec zobrazit nějakou hlášku, nebo něco udělat. Jediné rozumné použití vidím v úpravě odstavce, kdy se při uložení změn zavolá skript, který to zapíše na server. A i tak je to lepší udělat přes tlačítko, než vymýšlet bejkárny. Je mi líto, ale tahle diskuse se nyní stala bezpředmětnou, jenom se tu dohadujeme jako malé děti. Budeme-li se hádat dál, pak budou muset zakročit moderátoři. Raději zatnem tipec my, než oni, ne? Tak jak?
1Pupik1989
Profil
Může to mít na cokoliv, to už není naše věc. Podstatné je, že otázka byla vyřešena.
yFang
Profil
Nejjednodušší je použít na 2 řádky jQuery a nevynalézat znovu kolo. Navíc když se použije knihovna hostovaná na googlu, tak už s velkou pravděpodobností bude v cachi prohlížeče a nic navíc se stahovat nebude.
Chamurappi
Profil
Reaguji na yFanga:
tak už s velkou pravděpodobností bude v cachi prohlížeče
S jak velkou přesně? Nevěřím, že není zanedbatelná (i když mi to zatím nikdo nedovolil změřit na masách lidí). Aby to mělo aspoň nějaký účinek, musel by se celý svět shodnout na používání stejné verze.
Čína blokuje domény Googlu, takže pokud má stránka spolehlivě fungovat všem a všude na světě, je lepší si udělat vlastní kopii, když už. Ale i tak bych doporučil Herboltovi netahat stokilovou knihovnu kvůli takové drobnosti.


Reaguji na CZghosta:
To nebude fungovat všude.
Řekl bych, že kód 1Pupika1989 má šanci fungovat ve větším množství prohlížečů než ten tvůj, protože používá prehistorické schopnosti DOMu (možná až na ten nodeName, místo kterého bych použil spíš tagName).

používá rohodovací operátory, navíc ne moc šikovně (rozhodovací operátory patří do podmínek)
Logické AND && a OR || jsou v JS zkratky pro ternární operátor. Nevrací true/false, vrací vždy jeden z operandů v závislosti na pravdivosti prvního z nich.

Budeme-li se hádat dál, pak budou muset zakročit moderátoři.
Nevidím zde nic, proti čemu by se mělo jakkoliv zakročovat.
1Pupik1989
Profil
Chamurappi:
možná až na ten nodeName, místo kterého bych použil spíš tagName

No nodeName funguje od IE 6 a tagName už v IE 5.5. Tudíž děkuji za připomínku, opravím si skripty.

Možná psát nodeName mám ze zvyku, že je definován i u textových potomků a automaticky si to pamatuji s nodeType. Netuším proč jsem to ale potřeboval u textových potomků.

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: