Autor Zpráva
opicak
Profil
Dobrý den, potřeboval bych jak zjistit který radio button je označen(checked).
Mám např. takový to script
var hlasovani = document.getElementsByName('hlasovat')[0].value;
var parametry = 'hlasovat='+hlasovani;
xmlhttp.open("POST","get.php",true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send(parametry);

html
Ano<input type="radio" name="hlasovat" value="ano">
Ne<input type="radio" name="hlasovat" value="ne">

Na 1. řádku označuju první button ale já bych potřeboval nějak udělat aby se označil zaškrtlí button
Ernie
Profil
Za předpokladu, že vždy bude jeden z nich zaškrtnutý:
var hlasovani = (document.getElementsByName('hlasovat')[0].checked)?document.getElementsByName('hlasovat')[0].value:document.getElementsByName('hlasovat')[1].value;
opicak
Profil
Ernie:
díky

Za předpokladu, že vždy bude jeden z nich zaškrtnutý:
s tím samozřejmě počítám.
//edit
ale já právě potřebuju bez podmínek.
Když budu mít 5 možností na výběr tak to bude strašně rozsáhlí, není jíný způsob?

opicak
opicak
Profil
Tak už jsem si na to přišel sám, pro ty co mají podobný problém.
var radios = document.getElementsByName('hlasovat');
            //alert(radios.length);
            for(var i=0;i<radios.length;i++){
                if(radios[i].checked) {var hlasovani = radios[i].value};
            }
Witiko
Profil
opicak:
Ještě si můžeš předem hodnotu radios.length uložit do nějaké proměnné. Máme za to, že Array.prototype.length nejspíš není (alespoň v části prohlížečů) prostým atributem, ale je na něj nalepena getter funkce, takže se při každém zjištění jeho hodnoty opět kalkuluje velikost pole. Uložením velikosti pole předem můžeš dojít k zlepšení v rychlosti.

Udělal jsem menší test v prohlížeči Chromium:
(function() {
  var i,
      a = [],
      times = [],
      time,
      length = 999999999;
  a.length = length;

  // 1. test, 999999999x vyhodnocujeme a.length
  time = Date.now();
  for(i=0; i < a.length; i++) {}
  times.push(Date.now() - time);

  // 2. test, 999999999x vyhodnocujeme length
  time = Date.now();
  for(i=0; i < length; i++) {}
  times.push(Date.now() - time);

  console.log(times);
})();


První test byl vykonán za 6034ms.
Druhý test byl vykonán za 3927ms.

Každopádně u malých polí se jedná o neznatelný rozdíl.
Chamurappi
Profil
Reaguji na Witika:
Ještě si můžeš předem hodnotu radios.length uložit do nějaké proměnné. Máme za to, že Array.prototype.length nejspíš […]
V radios nemá Array, ale kolekci HTML elementů a u té je jisté (už z principu její živosti), že se při zjišťování length vždy přepočítají členové.
Witiko
Profil
Chamurappi:
Ano, v případě živého odkazu na část DOMu to ani jinak nejde. Nějak jsem si toho nevšimnul, v tom případě by mu pravděpodobně stačilo pouze:
var i = 0, hlasovani;
do{
  if(radios[i].checked) {
    hlasovani = radios[i].value;
    break;
  }
} while(radios[++i] !== undefined)


opicak:
Až teď jsem si všimnul: var hlasovani = radios.value v těle toho cyklu. Proměnné se nedeklarují více než jednou v celé funkci. Opak poukazuje na nepochopení principu na jakém funguje deklarace a přiřazení hodnoty proměnné a zacházení s first-class citizens kterými jsou neanonymní funkce a proměnné v javascriptu.
opicak
Profil
Witiko:
díky za tip, ale podle Chamurappi to tedá ani u mého případu nemá smysl dávat length do proměnné?

Až teď jsem si všimnul
tím chceš říct, že bych měl deklarovat proměnou před cyklem ?

Opak poukazuje na nepochopení principu na jakém funguje deklarace a přiřazení hodnoty proměnné a zacházení s first-class citizens kterými jsou neanonymní funkce a proměnné v javascriptu.
Tuto věto jsem moc nepochopil.

opicak
Witiko
Profil
opicak:
díky za tip, ale podle Chamurappiho to tedá ani u mého případu nemá smysl dávat length do proměnné?
Neprocházíš polem, ale souborem elementů. To znamená, že se nemusíš zaobírat délkou, ale jednoduše procházet, dokud nedojdeš k undefined - tedy ke konci pole - tak, jak ti to ukazuji v [#7]. Jako for cyklus by se to zapsalo takto:
for(var i = 0; radios[i] !== undefined; i++) { ... }
Postup je specifický pro pole elementů, u normálního pole můžou být jednotlivé prvky pole "řídké" - tzn. nedefinované, mající hodnotu undefined. Proto by se použil cyklus, který popisuješ v příspěvku [#4], jen by sis před cyklem předuložil délku pole (v případě že během cyklu nehodláš s polem manipulovat tak, že by se měnila jeho délka).

tím chceš říct, že bych měl deklarovat proměnou před cyklem ?
Především jen jednou. Ono prakticky více než jednou ke spuštění toho "var hlasovani = radios.value" nedojde, nicméně i tak je dobrým pravidlem deklarovat proměnné mimo tělo cyklu, ideálně na začátku funkce. Deklarace a přidělení hodnoty se dá oddělit. Tzn. může to vypadat nějak takhle:
for(var i = 0, hlasovani; radios[i] !== undefined; i++){
  if(radios[i].checked) {
    hlasovani = radios[i].value;
    break;
  }
}
A přidal jsem ti tam break, který přeruší cyklus po nalezení zaškrtnutého radio buttonu.
_es
Profil
Witiko:
To znamená, že se nemusíš zaobírat délkou, ale jednoduše procházet, dokud nedojdeš k undefined
Ak už ide o optimalizáciu na výkon, tak:
Na overenie, či nejaká premenná obsahuje objekt alebo hodnotu undefined netreba premennú porovnávať s globálnou premennou undefined, ale stačí overiť v podmienke samotnú premennú, ktorá sa automaticky skonvertuje na true alebo false. Teda namiesto:
if(x !== undefined)
stačí:
if(x)
V tomto prípade dokonca netreba overovať nič, lebo pokus o zistenie nejakej vlastnosti hodnoty undefined vyvolá chybu a teda ukončenie cyklu.
Witiko
Profil
_es:
namiesto: if(x !== undefined) stačí: if(x)
Mno, if(x) je tím samým co x == true a to se vyhodnotí stejně rychle jako x === true jen za předpokladu, že x je true. Nechápu jaká je výhoda v pomalejším přetypovávání, když nám jde o testování jedné konkrétní hodnoty, kterou je undefined?

V tomto prípade dokonca netreba overovať nič, lebo pokus o zistenie nejakej vlastnosti hodnoty undefined vyvolá chybu
Je to jedna z možností, if(radios[i].checked) skutečně vyvolá výjimku, pakliže je radios[i] undefined a logicky by k tomu ani nemělo dojít, pokud je nějaký z inputů checked, ale není to dvakrát pěkný styl psaní kódu. Ať každý zváží sám. :-)
_es
Profil
Witiko:
když nám jde o testování jedné konkrétní hodnoty, kterou je undefined
Ale undefined v tom výraze nie je konkrétna hodnota, ale globálna premenná, teda s pomalším prístupom ako nejaká lokálna, s hodnotou undefined.

Nechápu jaká je výhoda v pomalejším přetypovávání,
Tipujem, že to bude skôr rýchlejšie, len sa overí, či ide o objekt, lebo každý objekt je prevedený na true, teda nenastáva použitie metód valueOf či toString a je v tom výraze o jeden operátor a o jednu hodnotu menej.
Witiko
Profil
_es:
To tedy znamená, že typeof x === "undefined" je rychlejší než x === undefined?
_es
Profil
Witiko:
To znamená, že typeof x === "undefined" je rychlejší než x === undefined?
Asi ani nie.
Witiko
Profil
_es:
Tak jsem to otestoval a výsledky jsou zajímavé:
(function() {
  var i, x,
      times = [],
      time,
      length = Math.pow(10, 7);

  time = Date.now();
  for(i=0; i < length; i++) {if(!x){}}
  times.push(Date.now() - time);

  time = Date.now();
  for(i=0; i < length; i++) {if(x === undefined){}}
  times.push(Date.now() - time);

  time = Date.now();
  for(i=0; i < length; i++) {if(typeof x === "undefined"){}}
  times.push(Date.now() - time);

  console.log(times);
})();

Výsledky:
[60,  2889, 51]   v V8 JVM prohlížeče Chromium
[396, 5624, 1034] v prohlížeči Internet Explorer 9
[124, 2050, 53]   v Mozille Firefox 4.0.1
[24,  236,  769]  v Opeře 11.10

Průměr: 
  (!x)                       - 151ms
  (x === undefined)          - 2700ms
  (typeof x === "undefined") - 477ms

Funkce typeof se zdá být velmi implementačně závislá. Pomalost undefined skutečně tkví v její globálnosti. Stačí si však do hlavičky dané lokální funkce deklarovat bez hodnoty lokání proměnnou undefined a výsledky se rapidně změní.
_es
Profil
Witiko:
A to má výraz if(!x) ešte o jednu operáciu naviac, než testovanie na opačnú hodnotu.
Mne to zase vo FF 4.0.1 vyšlo [216, 67, 67].
Obávam sa však, že to testovanie nemusí byť korektné, keďže najnovšie prehliadače používajú rôzne optimalizácie a ak je za podmienkou prázdny príkaz môžu celú podmienku aj preskočiť. Tak isto môže byť optimalizácia, ak sa testuje stále ten istý výraz s tou istou premennou a prehliadač si môže zistiť, že sa premenná nemá počas cyklu ako zmeniť.
Witiko
Profil
_es:
a prehliadač si môže zistiť, že sa premenná nemá počas cyklu ako zmeniť.
To nevím, koneckonců javascript je turing-kompletní jazyk a předpovězení, jestli dojde během cyklu ke změně nějaké proměnné může být časově poměrně náročná úloha, jelikož cyklus může obsahovat teoreticky nekonečně mnoho uzávěr, prakticky je tu určitý call stack limit.
_es
Profil
Witiko:
předpovězení, jestli dojde během cyklu ke změně nějaké proměnné může být časově poměrně náročná úloha, jelikož cyklus může obsahovat teoreticky nekonečně mnoho uzávěr.
JS beží v jednom vlákne a ak v kóde nie je premenná nikde použitá a nedochádza tam napríklad k volaniu nejakých neznámych funkcií, tak je jasné, že sa tá premenná nemá ako zmeniť.
Voľakedy som spravil príklad na ukážku využitia obsadenia pamäte v rôznych prehliadačoch.
Dokiaľ nebola v tej vnorenej funkcii premenná x explicitne použitá, tak ju optimalizátory v prehliadačoch vymazali a uvoľnili pamäť a nebrali ohľad na nejaké teoretické „zálohy kontextu“ a pod.
Pokúsil som sa ten tvoj test vylepšiť:
(function() {
  var i, x = [],
      times = [],
      time,
      length =  Math.pow(10, 7),
      o = {x:1,y:2},
      u;
  for(i=0; i < length; i++) x[i]=o;

  i=0; time = Date.now();
  while(x[i++]);
  times.push(Date.now() - time);

  i=0; time = Date.now();
  while(x[i++] !== undefined);
  times.push(Date.now() - time);
  
  i=0; time = Date.now();
  while(x[i++] !== u);
  times.push(Date.now() - time);
    
  i=0; time = Date.now();
  while(x[i++] !== void 0);
  times.push(Date.now() - time);

  i=0; time = Date.now();
  while(typeof x[i++] !== "undefined");
  times.push(Date.now() - time);

  alert(times);
})();

MMMožno by bolo dobré toto vlákno rozčleniť, lebo sa dosť odbočilo mimo témy.
Witiko
Profil
Tento test:
Chromium V8 JVM:       [110, 2860, 153, 139, 66  ]
Internet Explorer 9:   [289, 5640, 398, 450, 3581]
Mozilla Firefox 4.0.1: [117, 2131, 226, 65,  64  ]
Opera 11.10:           [119, 150,  128, 128, 163 ]

Předchozí test:
Chromium V8 JVM:       [60,  2889, -,   -,   51  ]
Internet Explorer 9:   [396, 5624, -,   -,   1034]
Mozilla Firefox 4.0.1: [124, 2050, -,   -,   53  ]
Opera 11.10:           [24,  236,  -,   -,   769 ]

Zajímavý je výsledek Opery, kdy u posledního testu došlo k takřka pětinásobnému urychlení. Tady zdá se nevyhodnocování těla cyklu skutečně mělo efekt, což může poukazovat na jeho standardní hloupé vyhodnocování.
_es
Profil
Witiko:
V akom systéme testuješ FF?
Mne to vychádza: [75,57,57,57,251]
Nemáš spustený Firebug alebo ten skript nespúšťaš nejako zvláštne?
Witiko
Profil
_es:
Spouším to přes Firebug, při spuštění přes standardní konzoli jsou výsledky mírně jiné.
_es
Profil
Witiko:
Firebug spomaľuje beh JS, pri deaktivovanom Firebugu, či podobných pomôckach v iných prehliadačoch, by to mohlo byť výrazne odlišné.

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: