javascript undefined

En tråd i 'Javascript/Ajax' startet av kongen, 9 Mai 2015.

  1. kongen

    kongen kongemedlem

    Innlegg:
    2.728
    i en php fil har jeg denne koden

    PHP:
    echo 'javascript';
    denne blir hentet inn i en javascript fil

    PHP:
    function javaFunc() {
    var 
    javaRequest = new XMLHttpRequest();        
    javaRequest.open('get''java.php'true);
    javaRequest.onreadystatechange = function () {
        var 
    DONE 4;
        var 
    OK 200;
        if (
    javaRequest.readyState === DONE) {
            if (
    javaRequest.status === OK) {
                return 
    javaRequest.responseText;        
            }
        }
    }
    javaRequest.send(null);
    }
    document.getElementById("java").innerHTML javaFunc();
    og javascriptet blir hentet inn i en html fil

    PHP:
    <div id="java"></div>
    <
    script type="text/javascript" src="java.js"></script>
    men dette gir resultatet 'undefined' istedet for 'javascript'. Hvordan får jeg resultatet 'javascript'?
     
  2. adeneo

    adeneo Medlem

    Innlegg:
    1.611
    I JavaScript returnerer alle funksjoner "undefined" med mindre noe annet er spesifisert.
    Nå har du jo spesifisert dette med en "return" inni der, og antar selvfølgelig at den returnerer resultatet fra ajax forespørselen når du kjører funksjonen.

    Ajax står for "Asynchronous Javascript And XML", ajax er med andre ord asynkront.

    Når en funksjon er asynkron så betyr det at funksjonen kjøres med en gang, men gir resultat senere, mens resten av koden fortsetter å kjøre. Asynkrone ting må altså ha en callback hvor resultatet er tilgjengelig ettersom det ikke stanser tråden.

    I JavaScript gjelder dette stort sett timere, ajax, websockets og en del andre ting.

    Her er et eksempel som forhåpentligvis er enklere å forstå
    PHP:
    var test 0;
    setTimeout(function() {
        
    test 1;
    }, 
    1000);

    console.logtest ); // fortsatt 0, variablen endres ikke før om et sekund ?
    Timeouten venter 1 sekund, og så endres variablen, men resten av koden fortsetter likevel å kjøre. Det er det som er akynkron oppførsel.

    Ajax er noe av det samme
    PHP:
    var request = new XMLHttpRequest(); 

    request.open('get''java.php'true); 
       
    // den siste parameteren ovenfor, "true", angir om forespørselen er synkron eller asynkron
       // Denne skal alltid settes til true, synkron ajax er en uting, og er i utgangspunktet aldri tillatt.

    request.onreadystatechange = function () { 
        
    // legg merke til at dette er callback'en, den trigger på alle endringer i forspørselen, og 4 betyr at resultatet er mottatt

        
    if  ( request.readyState === && request.status === 200) {
               
    // du kan rett og slett ikke returnerer herfra, denne callback'en kjøres senere
            
    var response request.responseText
        }
    }
    request.send(null);
    og det er kanskje enda lettere å forstå med XMLHttpRequest i jQuery

    PHP:
    $.ajax({
        
    url 'java.php'
    }).done(function(response) { // callback
         // response er kun tilgjengelig her
    });
        
    // ikke her
    Så hva er løsningen, hvordan får man resultatet tilbake fra en funksjon?
    Den eneste løsninger er callbacks, enten det er i form av promises eller vanlige funksjoner, og koden må skrives slik at den fungerer med callbacks, som kan være litt plundrete noen ganger, men man må vente på at XMLHttpRequest kontakter "java.php" i bakgrunnen og laster inn innholdet i den filen, man har ikke noe annet valg.

    PHP:
    function javaFunc(callback) {
        var 
    javaRequest = new XMLHttpRequest();
       
        
    javaRequest.open('get''java.php'true);
       
        
    javaRequest.onreadystatechange = function () {
            if (
    javaRequest.readyState === && javaRequest.status === 200) {
                    
    callbackjavaRequest.responseText );
                }
            }
        }
        
    javaRequest.send(null);
    }

    javaFunc(function(data) {
        
    document.getElementById("java").innerHTML data;
    });
    Dette er noe alle som begynner med JavaScript treffer på før eller siden, og alle gjør stort sett samme feilen.
    På Stack Overflow har Felix fra Facebook vært så hyggelig å lage en slags kanonisk guide til asynkrone funksjoner, hvordan de virker, og hvordan man jobber med de, nettopp fordi det samme spørsmålet kommer opp hundre ganger hver eneste dag fra nye utviklere som støter på det samme problemet i forskjellige former

    http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call

    .
     
    kongen og Tonny Kluften liker dette.
  3. kongen

    kongen kongemedlem

    Innlegg:
    2.728
    Det virker. Kan man hente javascript slik også?

    Hvis jeg har denne javascripten

    PHP:
    var num1 0;
    var 
    num2 20;
    var 
    num30;

    function 
    klikkNum(num1) {
        if (
    num1 == 0){
            
    document.getElementById("java").innerHTML '<button onclick="klikkTot()">Klikk knappen</button>';
        } else if (
    num1 == 1){
            
    document.getElementById("java").innerHTML 'Du har klikket ' num1 ' gang. <button onclick="klikkTot()">Klikk mere</button>';
        } else {
            
    document.getElementById("java").innerHTML 'Du har klikket ' num1 ' ganger. <button onclick="klikkTot()">Klikk mere</button>';
        }
    }

    function 
    klikkTot() {
    if (
    num1 == num2) {
    document.getElementById("java").innerHTML 'Du har klikket 20 ganger';
    } else {
    num1++;
    klikkNum(num1);
    }
    }

    window.onload = function() {
    klikkNum(num1);
    }
    som puttes i en php fil

    PHP:
    echo "
    var num1 = 0;
    var num2 = 20;
    var num3= 0;

    function klikkNum(num1) {
        if (num1 == 0){
            document.getElementById(\"java\").innerHTML = '<button onclick=\"klikkTot()\">Klikk knappen</button>';
        } else if (num1 == 1){
            document.getElementById(\"java\").innerHTML = 'Du har klikket ' + num1 + ' gang. <button onclick=\"klikkTot()\">Klikk mere</button>';
        } else {
            document.getElementById(\"java\").innerHTML = 'Du har klikket ' + num1 + ' ganger. <button onclick=\"klikkTot()\">Klikk mere</button>';
        }
    }

    function klikkTot() {
    if (num1 == num2) {
    document.getElementById(\"java\").innerHTML = 'Du har klikket 20 ganger';
    } else {
    num1++;
    klikkNum(num1);
    }
    }

    window.onload = function() {
    klikkNum(num1);
    }
    "
    ;
    og hentes inn i den kjørende javascript filen.

    PHP:
    function javaFunc(callback) {
        var 
    javaRequest = new XMLHttpRequest();
       
        
    javaRequest.open('get''java.php'true);
       
        
    javaRequest.onreadystatechange = function () {
            if (
    javaRequest.readyState === && javaRequest.status === 200) {
                    
    callbackjavaRequest.responseText );
                }
            
        }
        
    javaRequest.send(null);
    }


    javaFunc(function(data) {
    // hvordan få importert javascript til å virke i denne filen
    });
    Hvordan kan man få de opprinnelige javascriptkodene til å virke i javascript filen som henter inn javascript fra ekstern fil?
     
  4. adeneo

    adeneo Medlem

    Innlegg:
    1.611
    Nå er jeg ikke helt sikker på hva du mener, men jeg tror det enkleste er å endre på settingene slik at javascript parses av PHP, noe sånt ( kun for å demonstrere ... les videre ) ...
    PHP:
    <FilesMatch"\.(js)$">
    AddHandler application/x-httpd-php .js
    </FilesMatch>
    i .htaccess, og så bare bruke en include
    PHP:
    // inne i "ting.js" e.l. ?

    javaFunc(function(data) {
        <?php include_once('klikk.js'); ?>
    });
    Men dette er dårlig praksis. For det første ønsker man ikke å parse mer enn nødvendig, for det andre ønsker man å cache javascript filene, som ikke blir mulig dersom de har dynamisk innhold, slik at alt i alt er det en elendig løsning som aldri bør brukes, fordi det tyder på feil design fra starten av.

    Det samme gjelder for echo'ing av javascript, det bør generelt sett unngås, og er så å si aldri nødvendig.
    Dersom du trenger data fra serveren kan du echo'et det ut i data-attributter i HTML'en og hente det derfra i stedet, for eksempel, det finnes mange løsninger på det problemet som er bedre.

    JavaScript bør strengt tatt holdes i eksterne .js filer, og ikke i PHP eller i HTML dokumenter, med noen svært få unntak. Når du er i ferd med å gjøre
    PHP:
    <?php

    echo '<script type="text/javascript"> ... '
    så gjør du noe feil, det samme med echo'ing av CSS fra serveren, det er slikt man skriver i egne filer, eventuelt med LESS eller SASS dersom man trenger det.

    For ditt tilfelle bør du bare klippe og lime den ene funksjonen inn i den andre funksjonen og ha alt i en ekstern JavaScript fil.
    Dersom du trenger data fra serveren kan du gjøre
    PHP:
    <div id="java" data-ting="<?php echo $ting?>">Heisann Sveisann</div>
    og henge dataene med
    PHP:
    var javaElem document.getElementById('java'); // cacher elementet slik
                                                   // at vi kun henter det en gang
    var data javaElem.getAttribute('data-ting');
    // nyere nettlesere har "dataset" som er litt greiere å jobbe med
    eller eventuelt også gjøre slik i .php filen som henter inn javascript filene
    PHP:
    <head>
        <script>
            var data = <?php echo json_encode($arr); ?>
        </script>
        <script src="ting.js"></script>
    men det lager en global variabel, som vi heller ikke liker noe særlig, men det er mye bedre enn å echo ut store mengder javascript.
     
    kongen og Tonny Kluften liker dette.

Del denne siden