eval() jak używać?

0

Witam, posiadam pewien, prawdopodobnie mały problem, jednak nie mogę się z nim uporać. Próbuję od wczoraj. Wczytuję mój kod javascript przez ajax'a, który go oczywiście nie interpretuje. Czytałem, że trzeba przepuścić przez eval(), jednak zupełnie nie mam pojęcia jak to zrobić. Może mi ktoś pomóc?

<?php
    $pozostalo = $uzytkownik['time1'] - time();
?>
   <script type='text/javascript'>        
        function liczCzas(ile) {
            godzin = Math.floor(ile / 3600);
            minut = Math.floor((ile - godzin * 3600) / 60);
            sekund = ile - minut * 60 - godzin * 3600;
            if (godzin < 10){ godzin = "0"+ godzin; }
            if (minut < 10){ minut = "0" + minut; }
            if (sekund < 10){ sekund = "0" + sekund; }
            if (ile > 0) {
                ile--;
                document.getElementById("zegar").innerHTML = godzin + ':' + minut + ':' + sekund;
                setTimeout("liczCzas("+ile+")", 1000);
            } else {
                document.getElementById("zegar").innerHTML = "[zakończono]";
            }
        }
    </script>
<span id='zegar'></span><?php echo "<script type='text/javascript'>liczCzas(".$pozostalo.")</script>";?> 
2

Nie używaj evala(), jeśli absolutnie nie musiz. Jest nawet powiedzenie: eval is evil.

Czemu ładujesz ajaxem całą wielką funkcję i -- dalej -- jej wywołanie? Funkcję zdefiniuj normalnie. Ajaxem ładuj tylko jej parametr ($pozostało). Gdy przyjdzie odpowiedź z serwera, odpalaj funkcję liczCzas(), przekazując jej ten parametr. I tyle.

0

hmm, masz na myśli, że cały kod js będzie na stronie wczytywanej i pobiorę tylko $pozostalo ?

0

To gdzie używasz evala()? W powyższym kodzie jest tylko ukryty eval() przy setTimeout, zresztą także zupełnie niepotrzebny.

edit: [bo edytowałeś posta i moja odpowiedź już jest bez sensu]
Tak. Pobierz tylko $pozostało.

0

nie wiem czemu mój zmęczony umysł dziś o ty nie pomyślał... Bardzo Ci dziękuję za pomoc, pewnie podarowałeś mi dodatkowe 3 godziny snu, ponieważ szukałbym do skutku...

0

@bswierczynski mógłbyś mi powiedzieć czemu w tym przypadku nie działa? nie dostrzegam błędu...
Mój ajax - tak przekazuję dane:

<script>
function ZapytaniePHP(url, post){
    if (window.XMLHttpRequest)xmlHttp = new XMLHttpRequest();
    else if (window.ActiveXObject)xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    if (xmlHttp == null){alert("Nie udało się zainicjować obiektu xmlHttpRequest!");return;}
    xmlHttp.onreadystatechange = function (){
        if (xmlHttp.readyState == 4 || xmlHttp.status == 200){
            document.body.innerHTML = xmlHttp.responseText;
        }
    }
    xmlHttp.open("POST", url, true);
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlHttp.send(post);
}
</script>

a tak moja dalsza część indexu:

<img onclick="ZapytaniePHP('index.php', 'menu=3')" style="...(tutaj nie ma co się rozpisywać dalej)/></a>
if(!empty($_POST['menu'])) {
require_once('licz.php');
echo "<script type='text/javascript'>liczCzas(". $pozostalo.")</script>";
}

licz.php:

$pozostalo = $uzytkownik['buduje1'] - time(); 

Nie liczę na gotowca, lecz na podpowiedź ^^

edit: tutaj jest cały kodzik:

<html>
<head>
<script type='text/javascript'>        
        function liczCzas(ile) {
            godzin = Math.floor(ile / 3600);
            minut = Math.floor((ile - godzin * 3600) / 60);
            sekund = ile - minut * 60 - godzin * 3600;
            if (godzin < 10){ godzin = "0"+ godzin; }
            if (minut < 10){ minut = "0" + minut; }
            if (sekund < 10){ sekund = "0" + sekund; }
            if (ile > 0) {
                ile--;
                document.getElementById("zegar").innerHTML = godzin + ':' + minut + ':' + sekund;
                setTimeout("liczCzas("+ile+")", 1000);

            } else {
                document.getElementById("zegar").innerHTML = "[zakończono]";
            }
        }
</script>
<script type='text/javascript'>
function ZapytaniePHP(url, post){
    if (window.XMLHttpRequest)xmlHttp = new XMLHttpRequest();
    else if (window.ActiveXObject)xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    if (xmlHttp == null){alert("Nie udało się zainicjować obiektu xmlHttpRequest!");return;}
    xmlHttp.onreadystatechange = function (){
        if (xmlHttp.readyState == 4 || xmlHttp.status == 200){
            document.body.innerHTML = xmlHttp.responseText;
        }
    }
    xmlHttp.open("POST", url, true);
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlHttp.send(post);
}
</script>
</head>
<body>
<a onclick="ZapytaniePHP('index.php', 'pozostalo=99999999999')">link</a>

<?php 
if(!empty($_POST['pozostalo'])){
	echo "czas:<script type='text/javascript'>liczCzas(".$_POST['pozostalo'].")</script>";
}
?>

</body>
</html>
 
0

@afc90:
Jednak nie robisz tego, co sugerowałem.

Nadal przesyłasz ajaxem skrypt, który próbujesz wykonać, wstawiając go za pomocą innerHTML -- a przeglądarka to umożliwia. Różnica taka, że teraz wysyłasz tym ajaxem nie całą funkcję oraz jej wywołanie, tylko samo wywołanie funkcji. To krok w dobrym kierunku, ale gdy wstawiasz za pomocą innerHTML tagi script, to one nigdy nie są wykonywane -- dotyczy to nawet tego jednolinijkowego skryptu, który zawiera tylko wywołanie liczCzas().

Przyjmij to do wiadomości. Tako rzecze specyfikacja HTML:
http://www.w3.org/TR/2008/WD-html5-20080610/dom.html#dynamic0
"script elements inserted using innerHTML do not execute when they are inserted."

Nie przesyłaj więc usilnie skryptu -- głową muru nie przebijemy ;). Niech serwer odpowiada na żądanie LICZBĄ. Tylko liczbą. Niczym innym! Żadnego wywołania funkcji, żadnego tagu script, nic! Tylko liczba!

Obecnie, gdy przychodzi odpowiedź, masz tę odpowiedź w responseText. I wstawiasz ją do dokumentu za pomocą innerHTML. Po sugerowanej przeze mnie zmianie, zamiast wstawiać odpowiedź do dokumentu, najnormalniej w świecie odpal sobie funkcję liczCzas() i jako argument przekaż jej otrzymają odpowiedź -- czyli liczbę. Z tego co widzę, to nawet nie będziesz musiał konwertować explicite responseText na liczbę (bo we własności responseText jest to liczba, ale w postaci ciągu znaków).

0

nie wiem zupełnie jak się za to zabrać... spróbuję jutro. Ten ajax jest dla mnie jak na razie trochę niejasny
edit: bo walczę... @bswierczynski nie bardzo wiem, w którym momencie ja ten skrypt wczytuję ajaxem, bowiem ten skrypt ma za zadanie tylko wysyłać dane postem. Dalej ifem muszę sprawdzić, czy takie dane zostały przekazane i w zależności od tego wyświetlić odpowiedni czas...
edit: podaję tutaj, to co udało mi się wyskrobać, jednak i to nie działa.

    <script type='text/javascript'>        
        function liczCzas(ile) {
            godzin = Math.floor(ile / 3600);
            minut = Math.floor((ile - godzin * 3600) / 60);
            sekund = ile - minut * 60 - godzin * 3600;
            if (godzin < 10){ godzin = "0"+ godzin; }
            if (minut < 10){ minut = "0" + minut; }
            if (sekund < 10){ sekund = "0" + sekund; }
            if (ile > 0) {
                ile--;
                document.getElementById("zegar").innerHTML = godzin + ':' + minut + ':' + sekund;
                setTimeout("liczCzas("+ile+")", 1000);
            } else {
                document.getElementById("zegar").innerHTML = "[zakończono]";
            }
        }

		
    </script>
<script type="text/javascript"> 
if (window.XMLHttpRequest) 
  { 
   ObiektXMLHttp = new XMLHttpRequest(); } 
   else if (window.ActiveXObject) 
      { 
       ObiektXMLHttp = new ActiveXObject("Microsoft.XMLHTTP"); } 

function getData(zrodlo, cel) { 
 if(ObiektXMLHttp) 
  {
   var cel = document.getElementById(cel);
   ObiektXMLHttp.open("GET", zrodlo);

ObiektXMLHttp.onreadystatechange = function() 
{
 if (ObiektXMLHttp.readyState == 4)
   {
    cel.innerHTML = ObiektXMLHttp.responseText; 
   }
}
ObiektXMLHttp.send(null); } } 
</script>

<input type = "button" value = "Pobierz" onclick = "getData('licznik.php', 'div')"> 
<div id="div">...</div>
<span id='zegar'></span> 
<script type='text/javascript'>
liczCzas(<?php echo $pozostalo; ?>)
</script>

licz.php:

 <?php $pozostalo = 9999999999 - time(); ?>

Zrobiłem tak jak powiedziałeś, pobrałem tylko $pozostalo i wyświetliłem liczCzas().

0

Nadal nie jest tak, jak napisałem. Być może masz problemy ze zrozumieniem asynchroniczności (gdy kiedyś "AJAX" był skrótem, asynchroniczność była pierwszym "A").

Poniższe linijki są chyba niepotrzebne?

<script type='text/javascript'>
liczCzas(<?php echo $pozostalo; ?>)
</script>

One się wykonują natychmiast po wyświetleniu strony i nie mają żadnego związku z żądaniem ajaxowym.

Gdy użytkownik klika w button, odpalana jest funkcja getData(). Obecnie, przygotowuje ona żądanie ajaxowe w obiekcie ObiektXMLHttp. Funkcja otwiera żądanie (metodą open()) i definiuje kod, który będzie się wykonywał przy każdym zmianie statusu żądania. Jest to metoda onreadystatechange. Ona zostanie wywołana, gdy połączenie zostanie otwarte, gdy żądanie będzie wysłane, gdy zacznie przychodzić odpowiedź i tak dalej. Czyli nasz kod w tej metodzie zostanie wywołany kilka razy gdy żądanie będzie realizowane!

Nas obchodzi tylko ostatni raz -- gdy żądanie będzie już zakończone. Po czym to poznamy? Po własności readyState -- będzie ona wtedy miała wartość 4. I to mamy właśnie w ifie. Gdy if przejdzie, wykonujemy czynność, którą chcemy wykonać po przyjściu odpowiedzi.

Obecnie, wstawiamy treść odpowiedzi do elementu cel. Czy to chcemy tak naprawdę zrobić? No chyba nie...

Przy okazji: zauważ, że linijka, która wysyła żądanie, czyli linijka z wywołaniem metody send(), jest niżej niż kod, który się wykona po przyjściu odpowiedzi na żądanie (kod ten jest w metodzie onreadystatechange). To dlatego, że najpierw musimy skonfigurować nasze żądanie i zdefiniować zawczasu, co chcemy zrobić gdy zmieni się jego status (za to odpowiada metoda onreadystatechange), a dopiero potem możemy wysłać już skonfigurowane żądanie.

W każdym razie, po przyjściu odpowiedzi wykonujemy obecnie tę linijkę:

cel.innerHTML = ObiektXMLHttp.responseText;

Czyli wstawiamy treść odpowiedzi (która siedzi w ObiektXMLHttp.responseText) do elementu cel. A my nie chcemy tego zrobić. Zamiast tego, chcemy w tym miejscu najzwyczajniej w świecie wywołać funkcję liczCzas(), przekazując jej za argument treść odpowiedzi.

BTW: zakładam tutaj, że chcesz, by wciśnięcie buttona powodowało, że zacznie być wyświetlany zegar odliczający czas zgodnie z tym, co odpowiedział serwer. Jeśli nie o to chodzi, to trochę głupio, że tego nie opisałeś.

0

masz rację, mam jeszcze problemy z ajaxe. Jak na razie to nie mam czasu uczyć się go od podszewki, muszę pomyśleć nad wolnym weekendem. Twoja wypowiedź trochę rozjaśniła mi tę technikę. Później będę miał trochę czasu, to zajmę się tym skryptem. Tym czasem dzięki za pomoc i zainteresowanie.
Tak, chodziło tutaj o zegar ^^.
edit: @bswierczynski wszystko działa jak należy. Dzięki za pomoc, jak na razie przy wielokrotnym wczytywaniu liczczas nakłada się na siebie i działa nieco nietypowo. To jednak zadanie dla mnie na później, bo teraz nie mam czasu. ^^ Nie taki ajax trudny jak go malują
edit2: @bswierczynski wiesz może jeszcze jak wywołać <input type="button" value="Pobierz" onclick="getData('licznik.php', 'div')"> bez onclick? Np, gdybym chciał wepchać to w warunek. np. if(x==1) { getData....}

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