Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Dynamiczne wczytywanie plików JS, eval() czy DOM
WebCM
post 21.08.2009, 13:46:41
Post #1





Grupa: Zarejestrowani
Postów: 375
Pomógł: 20
Dołączył: 28.07.2006

Ostrzeżenie: (0%)
-----


Tworzę grę logiczno-przygodową tylko w XHTML, CSS i JavaScript. Po uruchomieniu gry wyświetli się ekran główny z wyborem poziomu i opcjami (wygląd, język, muzyka OGG). Ewentualnie informacja o potrzebie aktualizacji przeglądarki.

1) Na początku trzeba załadować główny plik językowy i pobrać menu.

Przejdźmy do procesu ładowania poziomu.

2) Kod XHTML - tutaj raczej AJAX i wstawienie kodu do odpowiedniego obiektu <div>
3) Kod JS - informacje o pokojach, przedmiotach, funkcje, zmienne - dla ładowanego poziomu...
4) Plik językowy dla ładowanego poziomu.

Do końca nie zdecydowałem, czy będzie podział na poziomy, czy nie. W każdym razie 1) i 3) trzeba załadować dynamicznie.

Sposób 1. DOM
Tutaj wystarczy stworzyć za pomocą DOM obiekt <script> i dopiąć atrybut SRC. Problemy mogą być w IE, ale zawsze można sprawdzić, czy istnieją obiekty, które trzeba pobrać.

JSON + eval
Pliki pobieramy za pomocą AJAX, a potem zawartość wsadzamy do eval(). Panuje opinia, że eval() spowalnia skrypt.

Którym sposobem najlepiej ładować skrypty JS do tych celów? Ważne, by nie pojawiły się problemy nawet na IE 6.


--------------------
„Jesteśmy różni, pochodzimy z różnych stron Polski, mamy różne zainteresowania, ale łączy nas jeden cel. Cel ten to Ojczyna, dla której chcemy żyć i pracować.” Roman Dmowski
Go to the top of the page
+Quote Post
kamil4u
post 21.08.2009, 14:26:08
Post #2





Grupa: Zarejestrowani
Postów: 2 350
Pomógł: 512
Dołączył: 4.01.2009
Skąd: Wrocław / Świdnica

Ostrzeżenie: (0%)
-----


Cytat
Panuje opinia, że eval() spowalnia skrypt.

Eval spowalnia skrypt, gdyż (z tego co pamiętam) uruchamia na nowo praser JS.

Proponuję Sposób 1, choć najlepiej gdybyś przetestował dwa i sprawdził co jest szybsze, mniej zawodne smile.gif


--------------------
Go to the top of the page
+Quote Post
seth-kk
post 21.08.2009, 14:34:51
Post #3





Grupa: Zarejestrowani
Postów: 444
Pomógł: 79
Dołączył: 26.05.2009

Ostrzeżenie: (0%)
-----


google uzywa document.write();


--------------------
Go to the top of the page
+Quote Post
#luq
post 21.08.2009, 15:06:24
Post #4





Grupa: Zarejestrowani
Postów: 589
Pomógł: 91
Dołączył: 22.05.2008
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Taka mała uwaga.
Nigdy nie łącz JSON`a z evalem (kwestia bezpieczeństwa), używaj do tego JSON.parse.


--------------------
Moja gra - scraby.io
Go to the top of the page
+Quote Post
WebCM
post 21.08.2009, 17:16:28
Post #5





Grupa: Zarejestrowani
Postów: 375
Pomógł: 20
Dołączył: 28.07.2006

Ostrzeżenie: (0%)
-----


Teraz dowiedziałem się, że nowe przeglądarki mają natywną obsługę obiektu JSON. Skłaniam się właśnie do tego formatu ze względu na większą elastyczność. Oczywiście funkcje też można dołączać jako własności? winksmiley.jpg Dla starszych przeglądarek pozostanie eval(). Nie dołączam zewnętrznych bibliotek.

@seth-kk: document.write odpada. Skrypty 3) i 4) będą ładowane dopiero po wykonaniu akcji.

Wtedy w pliku level2.js mogę pominąć nazwy zmiennych - przynajmniej tak mi się zdaje:
Kod
{
    computer:
    {
        on: 1,
        disk: 0
    }
}

Być może jestem w błędzie i to wcale nie jest dobre rozwiązanie.


--------------------
„Jesteśmy różni, pochodzimy z różnych stron Polski, mamy różne zainteresowania, ale łączy nas jeden cel. Cel ten to Ojczyna, dla której chcemy żyć i pracować.” Roman Dmowski
Go to the top of the page
+Quote Post
erix
post 21.08.2009, 17:37:30
Post #6





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
Oczywiście funkcje też można dołączać jako własności? Dla starszych przeglądarek pozostanie eval(). Nie dołączam zewnętrznych bibliotek.

JSONP. Właściwie, to wszystkie przeglądarki umożliwiają przetwarzanie danych przez JSON, nawet IE6. biggrin.gif


--------------------

ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW!
Go to the top of the page
+Quote Post
WebCM
post 21.08.2009, 18:48:42
Post #7





Grupa: Zarejestrowani
Postów: 375
Pomógł: 20
Dołączył: 28.07.2006

Ostrzeżenie: (0%)
-----


Natywny parser w Firefoksie 3.5 JSON.parse() ogranicza mnie. Nie można wplątać funkcji:
Kod
{
    dosomething: function(z, c, b) { alert(c) }
}

Raczej nie napiszę logiki etapu tylko za pomocą zmiennych (czyt. własności obiektu), choć jest to możliwe. Musiałbym rozbudować silnik gry, aby obsłużyć wszystkie możliwe zdarzenia, np. użycie przedmiotów na określonych rzeczach, zmianę stanu urządzeń, tekst w zależności od tego, czy płyta / dyskietka jest włożona, czy prąd włączony... Czy jest sens aż tak kombinować? Raczej NIE.

Mam zamiar udostępnić grę do pobrania, więc pewnie pojawią się mirrory w sieci. Gdybym nawet użył JSON.parse(), wciąż pojawia się zagrożenie, że ktoś zmodyfikuje inną partię skryptu, aby wyciągnąć cookies lub przeprowadzić CSRF.

Poszukam jeszcze benchmarków i zdecyduję, co wykorzystać. AJAX i tak będzie potrzebny, by pobrać XHTML.


--------------------
„Jesteśmy różni, pochodzimy z różnych stron Polski, mamy różne zainteresowania, ale łączy nas jeden cel. Cel ten to Ojczyna, dla której chcemy żyć i pracować.” Roman Dmowski
Go to the top of the page
+Quote Post
zegarek84
post 21.08.2009, 19:27:46
Post #8





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


na upartego nie musisz używać AJAX'a do pobrania JSON winksmiley.jpg:
Howto Dynamically Insert Javascript And CSS - wystarczy podpiąć zdarzenie onload i odpalić odpowiednią funkcję na JSON...

wcześniej gdy pisali by nie używać eval to właśnie mieli na myśli o tych załączanych funkcjach jako metody winksmiley.jpg
Cytat(WebCM @ 21.08.2009, 19:48:42 ) *
Poszukam jeszcze benchmarków i zdecyduję, co wykorzystać. AJAX i tak będzie potrzebny, by pobrać XHTML.

no i tu znowu na upartego mając odpowiednią strukturę JSON mógłbyś na jego podstawie budować xhtml'a więc i ajax też nie jest przymusem ;p


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
WebCM
post 21.08.2009, 19:46:17
Post #9





Grupa: Zarejestrowani
Postów: 375
Pomógł: 20
Dołączył: 28.07.2006

Ostrzeżenie: (0%)
-----


Znam metodę z DOM. Eksperymentowałem. IE 8 niestety ma niepełną obsługę. Podzielę się wynikami:

Kod
function include(file, loaded)
{
    var js = document.createElement('script');
    js.type = 'text/javascript';
    js.src = file;

    //Wywołaj funkcję, gdy plik zostanie załadowany
    if(loaded)
    {
        js.onreadystatechange = function()
        {
            if(js.readyState == 'complete') loaded()
        };
        js.onload = loaded;
    }
    document.getElementsByTagName('head')[0].appendChild(js);
}

Funkcja dołącza dynamicznie skrypt JavaScript i opcjonalnie wywołuje po załadowaniu funkcję przekazaną do loaded.

Jak przeglądarki radzą sobie z tym? Testowałem w: IE 8, Chrome 2.0.172.33, Opera 9.61, FX 3.5, Safari 4.30.19.1

onload: Opera 9, Chrome 2, FX 3.5, Safari 4.30
onreadystatechange: IE 8, Opera 9.6

Internet Explorer
Studium przypadku - zazwyczaj wartość readyState kończy się na 'loaded'. Czasami 'complete'.

Opera
Własność readyState przyjmuje wartości 'interactive' i 'loaded'. Potem przenosi się do onload. Gdy dopuszczę wartość 'loaded' dla readyState, Opera wywoła funkcję przekazaną jako parametr kilka razy.

Chrome 2, Firefox 3.5, Safari 4.30
Obsługują tylko własność onload, więc nie ma problemu z wywołaniem funkcji w odpowiednim momencie. Na blogach można przeczytać, że w Safari kod w ogóle nie działa. Musieli to poprawić.

Można ewentualnie wykryć w onreadystatechange, czy obiekty są już dostępne.

Potrzebuję więcej argumentów przemawiających za DOM lub za eval() lub za AJAX + <script>.innerHTML.


--------------------
„Jesteśmy różni, pochodzimy z różnych stron Polski, mamy różne zainteresowania, ale łączy nas jeden cel. Cel ten to Ojczyna, dla której chcemy żyć i pracować.” Roman Dmowski
Go to the top of the page
+Quote Post
erix
post 21.08.2009, 20:03:43
Post #10





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
Obsługują tylko własność onload, więc nie ma problemu z wywołaniem funkcji w odpowiednim momencie. Na blogach można przeczytać, że w Safari kod w ogóle nie działa. Musieli to poprawić.

Przejrzyj źródła jQuery, bo chyba tam było jakieś obejście.

Cytat
lub za AJAX + <script>.innerHTML.

Możesz wczytać przecież skrypt z zewnętrznego źródła, albo tak, jak robi JSONP:
[JAVASCRIPT] pobierz, plaintext
  1. var a = {....}
  2. processData();
[JAVASCRIPT] pobierz, plaintext

Wtedy nie będziesz potrzebował żadnych zdarzeń, gdyż dane będą już wczytane. ;]


--------------------

ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW!
Go to the top of the page
+Quote Post
zegarek84
post 21.08.2009, 20:10:26
Post #11





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


jeśli w JSON i tak zamierzasz przesyłać funkcje w metodach to równie dobrze mógłbyś w DOM przesłać też ale na końcu skryptu funkcję inicjującą tą co jest już w window - mam na myśli tą co ma przejrzeć obiekt...

czyli np. coś w ten deseń:

temp={}; //tymczasowy kontener json
inicjuj(); //wszystko widać co i jak - wywołanie funkcji która ma się dobrać do obiektu temp

//edit
@erix mnie ubiegł...

Ten post edytował zegarek84 21.08.2009, 20:11:34


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 13.06.2025 - 07:40