js/jquery - odczyt z pliku co sekundę

0

Witam,
chciałbym napisać skrypt, który co sekund odczytuje zawartość pliku txt i wypisuje ta zawartość na ekranie, napisałem coś takiego:

<html>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
	<head>
		<script type="text/javascript">
			function read(){
			jQuery.get('test.txt', function(data) {
			var myvar = data;
			setInterval(document.write(myvar), 1000);
			});
			}
			read();
		</script>
	</head>
</html>

Problem polega na tym że zawartość pliku odczytywana jest tylko raz.

prosiłbym o poprawienie kodu lub jakieś wskazówki.

Z góry dzięki

 
``` ```
5

Bo to jest wywołanie funkcji document.write:

document.write(myvar)

Jak używasz go w ten sposób z setInterval:

setInterval(document.write(myvar), 1000);

To tak naprawdę jako pierwszy parametr funkcji setInterval podajesz WYNIK działania funkcji document.write. Przy czym document.write jest wywoływana natychmiast.

Może na innym przykładzie. Powiedzmy, że masz taką funkcję:

function alertAndReturn4() {
  alert("Cztery");
  return 4;
}

Jeśli zastosujesz coś takiego:

setInterval(alertAndReturn4(), 1000);

To natychmiast wywołujesz funkcję alertAndReturn4 -- bo te nawiasy () oznaczają wywołanie funkcji. Nasza funkcja jest wywoływana, wyświetla komunikat "Cztery" oraz zwraca wynik: liczbę 4. To właśnie ten wynik -- liczbę 4 -- przekazujesz do setInterval. Czyli tak, jakbyś napisał:

setInterval(4, 1000);

Bez sensu, prawda?

Do setInterval chcesz podstawić funkcję (której nie chcesz natychmiast wywoływać -- tym ma się zająć setInterval), a nie wynik wywołania funkcji. Musisz więc pominąć nawiasy () i napisać samą nazwę funkcji:

setInterval(alertAndReturn4, 1000);

To już zadziała. Przekazuje do setInterval funkcję alertAndReturn4 i ona będzie wywoływana co ok. sekundę. Co sekundę pojawi się więc komunikat.

Powstaje problem gdy chcesz przekazać funkcję, która oczekuje jakiegoś argumentu. Np. document.write oczekuje argumentu będącego napisem, który trzeba wyświetlić. Argumenty podaje się w nawiasach, a nawiasy oznaczają wywołanie funkcji, więc nie możesz ich użyć.

Możesz napisać funkcję opakowującą, która sama nie będzie potrzebowała argumentów, a wywoła funkcję z argumentami. W Twoim przypadku chcesz wywołać funkcję z argumentem document.write(myvar). Napisz więc sobie funkcję o nazwie np. writeMyVar:

// możesz to wstawić np. na początku skryptu
function writeMyVar() {
  document.write(myvar);
}

Zauważ, że nasza funkcja writeMyVar nie potrzebuje argumentów. Można ją więc przekazać do setInterval w działający sposób, bez wywoływania, tj. bez nawiasów:

setInterval(writeMyVar, 1000);

To dość częsty przypadek: tworzymy funkcję, której używamy tylko raz. Na szczęście JavaScript to język funkcyjny i pozwala na robienie różnych cudów z funkcjami. Np. pozwala na tworzenie funkcji anonimowych. Czyli takich, które nie mają nazwy. Skoro nie mają nazwy, to nie ma do nich normalnego dostępu i nie można ich wywoływać jak się chce. Ale można je wstawić w dowolne miejsce: tam, gdzie są potrzebne.

Napiszemy teraz funkcję anonimową, która robi dokładnie to samo co writeMyVar. Tyle że wstawimy ją od razu tam, gdzie ma się znaleźć -- jako argument setInterval -- i nie nadamy jej nazwy, bo nie potrzeba (i tak się nie będziemy do tej funkcji nigdzie indziej odnosić):

setInterval(function() {
  document.write(myvar);
}, 1000);

I to jest rozwiązaniem Twojego problemu.

0

Dziękuję bardzo za wyjaśnienie.
Poprawiłem i mam teraz coś takiego:

<html>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
	<head>
		<script type="text/javascript">
			function read(){
				jQuery.get('test.txt', function(data) {
					var myvar = data;
					setInterval(function() {
						document.write(myvar);
					}, 1000);
				});
			}
			read();
		</script>
	</head>
</html>

Działa to teraz w taki sposób:
-odpalam skrypt
-po sekundzie pokazuje się zawartość pliku 'test.txt'

tylko ja chciałbym żeby zmienna myvar 'aktualizowała się' co 1s. w ten sposób, że jeśli podczas działania skryptu zmienię zawartość pliku TXT to napis w przeglądarce również ulegnie zmianie (po max 1s.).

Jedyne co mi przychodzi do głowy to:

          <script type="text/javascript">
			function read(){
				jQuery.get('test.txt', function(data) {
					var myvar = data;
						document.write(myvar);
				});
			}
			setInterval(read, 1000);
		</script>

Według mnie skoro funkcja read wykonuje się co 1s. to na ekranie ca 1s. powinna się pojawić aktualna zawartość pliku TXT, tymczasem po odpaleniu skryptu i po upłynięciu 1s. pojawia mi się zawartość pliku i tak już zostaje do końca, gdy zmieniam zawartość pliku TXT nic się nie dzieje, aktualizacja pojawia się dopiero po odświeżeniu.

Z góry dzięki za pomoc.

1

To jest cały twój skrypt? Wygląda, jakby się gdzieś JavaScript sypał. Używasz Firefoxa - ściągnij sobie dodatek Firebug lub zobacz wbudowaną konsolę błędów (menu Narzędzia). Nie ma żadnych ostrzeżeń? IMO używanie setInterval w tym miejscu nie jest bezpieczne, wykonanie żądania może zająć więcej niż sekundę i wtedy zostanie wysłane kolejne asynchroniczne żądanie, lepiej wysyłać zapytania w sposób uporządkowany, jedno po drugim.

          <script type="text/javascript">
                        function read(){
                                jQuery.get('test.txt', function(data) {
                                        var myvar = data;
                                        document.write(myvar);
                                        setTimeout(read, 1000);
                                });
                        }
                        read(); //pierwsze wywołanie
                </script>

Dodatkowo document.write dopisze daną treść do kodu strony, a nie podmieni ją - nie wiem czy to zamierzone.

[dodano]
I jeszcze jedno, jeśli nie ma żadnych błędów, to możliwe że plik test.txt został po prostu zakeszowany w pamięci przeglądarki. Możesz to ominąć w prosty sposób, wystarczy dodać jakiś losowy parametr na końcu linku, dzięki czemu będzie on unikalny. Całość będzie wtedy wyglądała tak:

          <script type="text/javascript">
                        function read(){
                                jQuery.get('test.txt?random=' + Math.random(), function(data) {
                                        var myvar = data;
                                        document.write(myvar);
                                        setTimeout(read, 1000);
                                });
                        }
                        read(); //pierwsze wywołanie
                </script>
0

Generalnie proponuję unikać document.write by sobie nie narobić problemów. Uaktualniaj zawartość jakiegoś tagu zamiast tego.

0

tylko że dokument w tym miejscu jest już zamknięty i wywołanie document.write spowoduje otworzenie nowego dokumentu, a tym samym nadpisanie całej strony - w tym skryptu, który przestanie w tym miejscu działać

dlatego zamiast document.write użyj innerText / HTML (odpowiednik w jQuery - text() / html()) jakiegoś elementu, przykładowo:

i zamiast document.write(myvar) dajesz
$('#testcontent').text(myvar);

1 użytkowników online, w tym zalogowanych: 0, gości: 1