Avatar billede hcs89 Nybegynder
24. marts 2009 - 20:44 Der er 8 kommentarer og
1 løsning

setTimeout med lokal variabel

Den følgende kode skulle gerne generere et felt, der automatisk talte
opad fra 0.
ved at trykke på knappen 'hold' skulle man kunne fange værdien af
variablen 'n' gemme den (som 'm') og så efter 3 sek, få den skrevet i
'field2'-feltet.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://
www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
var num = 0
var m
function count()
{
        document.getElementById("field").value = num;
        num++
        setTimeout("count()",1000);
}

function hold()
{
        var m=n;
        t = setTimeout("document.getElementById('field2').value = m;",3000);
}</script>

<title>Untitled Document</title>
</head>
<input type="text" id="field" /> <input type="button" value="start
count" onclick="count()" />
<input type="text" id="field2" /> <input type="button" value="hold"
onclick="hold()" />
<body>
</body>
</html>

Det virker ikke. Jeg er et sikker på at problemet er at den lokale
variabel m bliver slettet efter af funktionen løber ud (funktionen
løber videre efter at timeoutet er blevet startet - og når således at
afslutte)
er der nogen der har en ide om hvordan problemet kan løses?
det duer ikke at erklære en global variabel og så give dén den
aktuelle værdi. skal være sådan så hvis man trykker på hold to gange i
træk bliver der fanget to forskellige værdier og vist respektivt 3 sek
efter klikket.
--synes selv det er lidt af en udfordring håber at der er nogen der
kan hjælpe!

(er selvfølgelig ikke denne her kode jeg skal have til at virke.. er
bare et eksempel jeg har oprettet for at isolere problemet)
Avatar billede olebole Juniormester
25. marts 2009 - 00:33 #1
<ole>

<script type="text/javascript">
var num = 0
var m
function count()
{
        document.getElementById("field").value = num;
        num++
        setTimeout("count()",1000);
}

function hold()
{
        var m=num;
        t = setTimeout(function(){document.getElementById('field2').value = m},3000);
}</script>

/mvh
</bole>
Avatar billede olebole Juniormester
25. marts 2009 - 00:37 #2
- eller bare for sjov en mere eksotisk version:

<script type="text/javascript">
var num = 0
var m
function count()
{
        document.getElementById("field").value = num;
        num++
        setTimeout("count()",1000);
}

function funcFactory(nVar) {
    return (function(){
        document.getElementById('field2').value = nVar;
    });
}

function hold()
{
        var m=num;
        var fn = funcFactory(m);
        t = setTimeout(fn,3000);
}</script>
Avatar billede hcs89 Nybegynder
25. marts 2009 - 19:58 #3
Ej hvor fedt.. det virker!
Tak skal du have

det er ret unødvendigt at deklarere variablen i starten af scriptet..
havde prøvet noget lignende.. det er detder function(){...}, der på en eller andet måde gør at hold ikke løber færdig, eller hvad? hvordan virker det? har ikke set det før.

opret et svar hvis du vil have nogle point!
Avatar billede olebole Juniormester
25. marts 2009 - 20:17 #4
Ja, 'var m' er ganske unødvendigt i begyndelsen. Dén variabel bruger vi faktisk aldrig. I stedet bruger vi denne: 'var m=num' - og det er jo to forskellige variabler - blot med samme navn. De kender ikke hinanden - og kommer aldrig til at mødes  ;o)

Det andet er en større og lidt kompleks forklaring, men 'hemmeligheden' hedder closure.

En closure er en feature ved ECMAScript - herunder JavaScript. Det er i korte træk et objekt, der f.eks. opstår, når en funktion kaldes. Da vil alt i funktionens indre scope 'kende hinanden' i den tilstand, der var gældende i dét præcise øjeblik, funktionen blev kaldt.

Du kan evt. kikke her for lidt mere uddybning:
    https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Working_with_Closures
Avatar billede olebole Juniormester
25. marts 2009 - 21:21 #5
Closures er en fuldstændig genial - men dramatisk undervurderet - feature. De kan bruges på alle mulige, kreative måder, men som altid er det en god idé at tænke sig om og undlade at overgøre noget. Husk at læse, hvad der skrives om performance:
    https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Working_with_Closures#Performance_considerations
Avatar billede olebole Juniormester
25. marts 2009 - 21:30 #6
PS: Hvis du læser om closures på WWW, vil du uden tvivl støde på kommentarer om fatal memory leaking i IE p.gr.a. dens elendige garbage collection i forbindelse med closures, DOM og circular references.

Problemerne har altid eksisteret i IE, men de blev accentueret i forbindelse med den øgede brug af Ajax - og deraf følgende markant stigning i antallet af DOM-operationer i samme dokument.

Da MS ønskede at følge markedet og bruge Ajax i deres indtægtsgivende produkter, var de nødt til at gøre noget ved IE's garbage collection - og problemerne blev i alt overvejende grad løst via en sikkerhedsopdatering i 2007.
Avatar billede hcs89 Nybegynder
26. marts 2009 - 19:40 #7
æh ok.. der er ihvertfald noget at arbejde videre med ;)
mane tak skal du have..
Avatar billede olebole Juniormester
26. marts 2009 - 22:27 #8
Du ku' jo bare lade være med at spørge!  ;D

Måske en lidt 'populariseret' forklaring kan hjælpe. Det der ligger mellem { og } i en funktion, lærer hinanden at kende i det øjeblik, funktionen kaldes.

Her lærer variablen bar den anonyme funktion inde i setTimeout-kaldet hinanden at kende, når funktionen foo bliver kaldt.
Når timeout'en et sekund senere kalder den anonyme funktion, ved denne, at variablen bar indeholder '12345' - for det gjorde den, da de lærte hinanden at kende:

function fooBar(num) {
    alert(num);
}
function foo() {
    var bar = 12345;
    setTimeout( function(){fooBar(bar)}, 1000 );
}

Håber, det hjalp lidt. Tak for points  =)
Avatar billede hcs89 Nybegynder
27. marts 2009 - 13:38 #9
lidt bedre  -  tak :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester