Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem JavaScript

Zdravím.
Proč je u toho vždý funkční až ten posledni div?
Muže je mezi sebou popřehazovát, ale vžda jen ten poslední.

<!DOCTYPE html>
<html>
<body>

<div id="shm/teplota_obyvak"" class="data">Žádná data :(</div>
<div id="shm/teplota_koupelna" class="data">Žádná data :(</div>
<div id="shm/teplota_loznice" class="data">Žádná data :(</div>
<div id="shm/teplota_pokoj" class="data">Žádná data :(</div>

<script>
function nactiData() {
  var data = document.getElementsByClassName("data");

  for (var i = 0; i < data.length; i++) {
    var soubor = data[i].getAttribute("id")
   
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById(soubor).innerHTML =
        this.responseText;
      }
    };
    xhttp.open("GET", soubor, true);
    xhttp.send();
  }
}
nactiData();

setInterval(function () {
  nactiData();
}, 10000);
</script>

</body>
</html>
Předmět Autor Datum
https://stackoverflow.com/questions/13077828/for-loop-in-javascript-outputs-value-only-from-last-ite…
Mlocik97 31.03.2019 16:40
Mlocik97
Jsem to asi špatně pochopil :.( Už to nefunguje vubec for(var i = 0;i < 10;i++){ var ii = i; setTim…
Leo1 31.03.2019 17:23
Leo1
(function(soubor) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (th…
Wikan 31.03.2019 17:26
Wikan
S toho jsem nějak mimi. V linuxu se alespon trochu orientují ale JS vidím dnes poprve. Potřebují to…
Leo1 31.03.2019 17:48
Leo1
Však Vám to Wikan celé napsal, len to vložte do cyklu for() v setTimeout()... tam jak ste mali funkc…
Mlocik97 31.03.2019 17:50
Mlocik97
setInterval(function () { var data = document.getElementsByClassName("data"); for (let i = 0; i < d…
Mlocik97 31.03.2019 18:04
Mlocik97
kdyz napíšete var hocikde i na trebars na konci funkcie, tak sa vždy interpetuje jak kdyby byl dekla…
Mlocik97 31.03.2019 17:29
Mlocik97
Vysledek uplně stajný jako v tom mém.:.( Žádná data :( Žádná data :( Žádná data :( 23.2|56.0
Leo1 31.03.2019 18:24
Leo1
Co přesně tam máš za kód? Určitě jsi načetl aktuální verzi stránky a ne z cache?
Wikan 31.03.2019 18:27
Wikan
<!DOCTYPE html> <html> <body> <div id="shm/teplota_koupelna" class="data">Žádná data :(</div> <div…
Leo1 31.03.2019 18:55
Leo1
xhttp.send(); } })(soubor); Smaž tu samotnou složenou závorku, je tam navíc.
Wikan 31.03.2019 18:58
Wikan
xhttp.open("GET", soubor, true); xhttp.send(); })(soubor); } }, 10000); Pokud jsem to neposmolil t…
Leo1 31.03.2019 19:52
Leo1
A už sis teda zkontroloval, že se ti to nenačítá z cache?
Wikan 31.03.2019 20:13
Wikan
A to zjistím jak? Ony se načitají všechní 4 teploty ale vpisují se postupně do toho posledního DIV
Leo1 31.03.2019 20:22
Leo1
Stiskni v prohlížeči Ctrl + F5.
Wikan 31.03.2019 20:29
Wikan
tak som to fakt zle skopíroval... ja tak nenávidím psaní na mobilu...
Mlocik97 31.03.2019 20:07
Mlocik97
Ne ne, už jsem ji tam měl blbě já.
Wikan 31.03.2019 20:13
Wikan
Ak zmeníš v pôvodnom programe riadok "var" na "let" v riadku "var soubor = data[i].getAttribute('id'…
moose 31.03.2019 20:52
moose
pravda ja debil, sám som napsal že to treba zmeniť za let, ale když som mu psal kód tak som tam dal…
Mlocik97 31.03.2019 21:48
Mlocik97
Děkují moc :-D
Leo1 01.04.2019 08:25
Leo1
Ještě kdyby jsi tak napsal, co jsi nakonec udělal.
Wikan 01.04.2019 08:27
Wikan
ctrl+c a ctrl+v to poslední, co tu dál moose :-D Mužů ještě jednu prosbu. Jak třeba tu hodnotu ze s…
Leo1 01.04.2019 09:16
Leo1
Máš ji přece v this.responseText. S ní si pak můžeš dělat, co chceš.
Wikan 01.04.2019 10:25
Wikan
Aha, už to chapu :-) Zatím jen pokusy ale pro mně bude lepší něco takoveho. <!DOCTYPE html> <html>…
Leo1 01.04.2019 11:21
Leo1
Bych měl ještě jeden dotaz. Jak umístit na stránku obrázek tak, aby šel přes JS měnit. Třeba takto.…
Leo1 04.04.2019 09:26
Leo1
možno je vhodnejšie do HTML napsať: <div id="obrazok"> <img src="a.png" id="a" class="" alt=""> <i…
Mlocik97 04.04.2019 09:41
Mlocik97
Můžete vysvětlit, jak funguje toto?( xhttp. {}; ) xhttp. { if (podminka) { document.getElementById…
cina kvality 04.04.2019 21:51
cina kvality
Kde jsi viděl takovou konstrukcí? To snad ani nemůže fungovat.
Wikan 04.04.2019 21:56
Wikan
Následující řádek za new XMLHttpRequest();
cina kvality 04.04.2019 21:57
cina kvality
Na tom řádku je toho ale poněkud více.
Wikan 04.04.2019 21:59
Wikan
Aha, asi nějaká chyba parsování... Prostě mi to zamlčelo ve všech příspěvcích to, že toho je poněkud… poslední
cina kvality 04.04.2019 22:02
cina kvality
(function(soubor) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById(soubor).innerHTML =
        this.responseText;
      }
    };
    xhttp.open("GET", soubor, true);
    xhttp.send();
  }
})(soubor);

Však Vám to Wikan celé napsal, len to vložte do cyklu for() v setTimeout()... tam jak ste mali funkci "nactiData()" data pak pouzijete za tym. Aj bych Vám to napsal, kdybych nebyl na mobilu vo vlaku. Ostatne nechápem ani to prečo si nepomozete knihovnou nebo frameworkom.

 
setInterval(function () {
  
  var data = document.getElementsByClassName("data");

  for (let i = 0; i < data.length; i++) {
    var soubor = data[i].getAttribute("id") ;

    (function(soubor) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById(soubor).innerHTML =
        this.responseText;
      }
    };
    xhttp.open("GET", soubor, true);
    xhttp.send();
  }
})(soubor);
  }

}, 10000);

dufam som to na mobile napsal a nakopíroval spravne a neusli mi zatvorky...

kdyz napíšete var hocikde i na trebars na konci funkcie, tak sa vždy interpetuje jak kdyby byl deklarovany na začiatku funkcie, je viazany na scope funkcie. Môžete použiť let ktory je viazaný na scope bloku, teda i samotneho cyklu. Ak volate funkciu vo vnutry cyklu, a vo volanej funkcii chcete použiť premennú iteracie, musite ho predať ako parameter. Logickejsie je ale to prepsat tak, aby ste mali iterator v bloku kde ho pouzivate, ako napríklad vo Vašom prípade pre výber prvku z arrayu. Ja bych tu funkci oddelil inak, tak jak to napsal Wikan.

Odporúčam Vám si nájsť neco o uzaveroch, closures. Ak to pochopíte, už takéto chyby budete vedieť vyriešiť.

<!DOCTYPE html>
<html>
<body>

<div id="shm/teplota_koupelna" class="data">Žádná data :(</div>
<div id="shm/teplota_koupelna" class="data">Žádná data :(</div>
<div id="shm/teplota_loznice" class="data">Žádná data :(</div>
<div id="shm/teplota_pokoj" class="data">Žádná data :(</div>

<script>

setInterval(function () {

var data = document.getElementsByClassName("data");

for (let i = 0; i < data.length; i++) {
var soubor = data[i].getAttribute("id") ;

(function(soubor) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById(soubor).innerHTML =
this.responseText;
}
};
xhttp.open("GET", soubor, true);
xhttp.send();
}
})(soubor);
}

}, 10000);

</script>

</body>
</html>

xhttp.open("GET", soubor, true);
xhttp.send();

})(soubor);
}
}, 10000);

Pokud jsem to neposmolil tak furt to same.

Nudím se v prací tak hledam a zkoušim to co je na w3schools.com

Toto mi take funguje.

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
$("#div1").load("shm/teplota_pokoj");
});
});
</script>
</head>
<body>

<div id="div1"><h2>Let jQuery AJAX Change This Text</h2></div>
<button>Get External Content</button>
</body>
</html>

Není pak lepší přejmenovat ty div - "div1", "div2"

Ak zmeníš v pôvodnom programe riadok "var" na "let" v riadku "var soubor = data[i].getAttribute('id')", tak to začne fungovať.

Dôvod bol už napísaný - je to kvôli tomu, že premenné deklarované pomocou var sú naviazané na funkciu. To znamená, že premenná soubor použitá v obsluhe udalosti onreadystatechange je stále jedna a tá istá premenná pre všetky iterácie cyklu. Takže každá iterácia nastaví hodnotu premennej soubor na identifikátor požadovaného elementu a po skončení cyklu táto premenná obsahuje posledný identifikátor a obsluha udalosti sa vykonáva až po ukončení cyklu.

Osobne by som to napísal takto (XMLHttpRequest by som použil iba ak by som musel podporovať nejaký zastaralý prehliadač, ako napr. IE11 - resp. skôr by som použil polyfill a transpiler):

<!DOCTYPE html>
<html>
	<body>
		<div data-url="shm/teplota_obyvak">Žádná data :(</div>
		<div data-url="shm/teplota_koupelna">Žádná data :(</div>
		<div data-url="shm/teplota_loznice">Žádná data :(</div>
		<div data-url="shm/teplota_pokoj">Žádná data :(</div>

		<script>
			const dataElements = [...document.querySelectorAll('div[data-url]')];

			function loadData() {
				dataElements.forEach(async dataElement => {
					const response = await fetch(dataElement.dataset.url);
					if (response.ok) {
						dataElement.textContent = await response.text();
					}
				});
			}

			loadData();

			setInterval(loadData, 10000);
		</script>
	</body>
</html>

Aha, už to chapu :-)

Zatím jen pokusy ale pro mně bude lepší něco takoveho.

<!DOCTYPE html>
<html>
<body>

<div id="demo">Žádná data :(</div>

<script>
function nactiKotel() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "shm/teplota_kotel", true);
xhttp.send();
}

setInterval(function () {
nactiKotel();
}, 10000);
</script>

</body>
</html>

Akorat volat tu funkcí s parametrem nactidata("shm/teplota_kotel");
A pak zpracovat a vypsat až ve funkci setInterval

Bych měl ještě jeden dotaz.
Jak umístit na stránku obrázek tak, aby šel přes JS měnit.

Třeba takto.

<script>
var cislo = 1;

if(cislo == 0){document.write("cislo je 0");
}
else{document.write("cislo je 1");
}
</script>

0 = jeden obrazek
1 = jiný obrazek

možno je vhodnejšie do HTML napsať:


<div id="obrazok">
    <img src="a.png" id="a" class="" alt="">
    <img src="b.png" id="b" class="skryt" alt="">
<div>

do CSS:


.skryt {
    display: none;
}

a v JS by ste prepínali triedy.
(ukážka v jQuery)

$("#tlacitko").on('click', function() {
    $("#a").toogleClass("skryt");
    $("#b").toogleClass("skryt");
}

Můžete vysvětlit, jak funguje toto?( xhttp. {}; )


   xhttp. {
      if (podminka) {
        document.getElementById(soubor).innerHTML =  this.responseText;
      }
    };

A chybí tam středník (pokud není nepovinný v dané implementaci, ale v Internet exploreru by to neprošlo)

Problém bude nejspíš v this, je někdy záludné a v určitých případech je nutné si uložit pomocnou proměnnou novethis=this a potom pracovat uvnitř funkce s novethis.

Obecně je to problematika closures, což jsou je věc týkající se toho, zda uvnitř funkce jsou dostupné proměnné z vnější (a jakým způsobem). Funkce ve své podstatě by měly operovat pouze proměnnými, které dostanou v argumentech. Ale tak to není a proto i funkce operují s proměnnými dostupnými z nadřazeného scope (zjednodušeně globální proměnné)

doporučení: není nutné dávat všem prvkům class=data, stačí je dát do nadřazeného bloku:


div(id=prvky)
-span(id=teplota)
-span(id=tlaky)

následně document.querySelectorAll("#prvky > span") 
=> dá seznam 4 prvků

Zpět do poradny Odpovědět na původní otázku Nahoru