Autor | Zpráva | ||
---|---|---|---|
opicak Profil |
#1 · Zasláno: 7. 5. 2011, 13:31:29 · Upravil/a: opicak
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 |
#2 · Zasláno: 7. 5. 2011, 13:39:46
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 |
#3 · Zasláno: 7. 5. 2011, 13:49:39 · Upravil/a: opicak
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 |
#4 · Zasláno: 7. 5. 2011, 14:27:25 · Upravil/a: opicak
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 |
#5 · Zasláno: 7. 5. 2011, 15:15:17 · Upravil/a: Witiko
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 |
#6 · Zasláno: 7. 5. 2011, 16:25:27
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 |
#7 · Zasláno: 7. 5. 2011, 16:31:45 · Upravil/a: Witiko
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 |
#8 · Zasláno: 7. 5. 2011, 21:37:21 · Upravil/a: opicak
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 |
#9 · Zasláno: 8. 5. 2011, 00:17:39 · Upravil/a: Witiko
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++) { ... } „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; } } |
||
_es Profil |
#10 · Zasláno: 8. 5. 2011, 00:38:56
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) if(x) undefined vyvolá chybu a teda ukončenie cyklu.
|
||
Witiko Profil |
#11 · Zasláno: 8. 5. 2011, 10:49:34 · Upravil/a: Witiko
_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 |
#12 · Zasláno: 8. 5. 2011, 12:24:00
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 |
#13 · Zasláno: 8. 5. 2011, 12:51:14 · Upravil/a: Witiko
_es:
To tedy znamená, že typeof x === "undefined" je rychlejší než x === undefined? |
||
_es Profil |
#14 · Zasláno: 8. 5. 2011, 12:56:21
Witiko:
„To znamená, že typeof x === "undefined" je rychlejší než x === undefined?“ Asi ani nie. |
||
Witiko Profil |
#15 · Zasláno: 8. 5. 2011, 13:09:22 · Upravil/a: Witiko
_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 |
#16 · Zasláno: 8. 5. 2011, 13:40:51
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 |
#17 · Zasláno: 8. 5. 2011, 14:22:28 · Upravil/a: Witiko
_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 |
#18 · Zasláno: 8. 5. 2011, 15:01:27 · Upravil/a: _es
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 |
#19 · Zasláno: 8. 5. 2011, 15:34:30
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 |
#20 · Zasláno: 8. 5. 2011, 15:42:18
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 |
#21 · Zasláno: 8. 5. 2011, 17:18:44
_es:
Spouším to přes Firebug, při spuštění přes standardní konzoli jsou výsledky mírně jiné. |
||
_es Profil |
#22 · Zasláno: 8. 5. 2011, 17:29:44 · Upravil/a: _es
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é. |
||
Časová prodleva: 13 let
|
0