Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    New to the CF scene
    Join Date
    Sep 2011
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Exclamation 2 noobie functions

    hey , i got 2 function , the one working and the other one is'nt

    heres the functions :

    Code:
                            var toDisplay = "f";
    			function human(){
    				var toAdd = toDisplay.substring(0,1);
    				setTimeout(human , 500);
    				document.getElementById('box').innerHTML += toAdd;
    			}
    			human(); // works (display "f" every half a sec)
    			
    			function human2(toDisplay2){
    				var toAdd = toDisplay2.substring(0,1);
    				var t = setTimeout("human2(toDisplay2)" , 500);
    				document.getElementById('box').innerHTML += toAdd;
    			}
    			human2("dsd"); // not working (only display "d" and stop)
    the first function works ( keep printing "f" every 0.5 sec )
    the second function only work once and than stop ( print "d" and than stop )

    what's the problem with the second function?

    thanks , Mor.

  • #2
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,536
    Thanks
    80
    Thanked 4,490 Times in 4,454 Posts
    That's because when the timeout fires, the code tries to execute *exactly* what you gave there, in the setTimeout:
    Code:
        human2(toDisplay2)
    But by that time, the variable toDisplay2 no longer exists, so you get an error.

    You have to code that this way:
    Code:
    	function human2(toDisplay2){
    		var toAdd = toDisplay2.substring(0,1);
    		setTimeout("human2('" + toDisplay2 + "')" , 500);
    		document.getElementById('box').innerHTML += toAdd;
    	}
    	human2("dsd");
    No point in assigning the setTimeout to the variable t because that variable, also, disappears as soon as the human2 function finishes.

    p.s.: You can, of course, reverse the quotes and apostrophes. Makes no difference.
    Code:
    		setTimeout('human2("' + toDisplay2 + '")' , 500);
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #3
    Regular Coder
    Join Date
    Aug 2010
    Posts
    974
    Thanks
    19
    Thanked 212 Times in 210 Posts
    Here is another way ...

    Code:
    <body>
    <div id="box"> </div>
    </body>
    <script>
    function human2(toDisplay2){
          (function inner(){	
    	var toAdd = toDisplay2.substring(0,1);
    	setTimeout(inner , 500);
    	document.getElementById('box').innerHTML += toAdd;})()
    			}
    			human2("dsd"); 
    </script>
    this way toDisplay2 continues to exist.
    Last edited by DaveyErwin; 09-08-2011 at 03:00 AM.

  • #4
    Regular Coder
    Join Date
    Aug 2010
    Posts
    974
    Thanks
    19
    Thanked 212 Times in 210 Posts
    In case you get tired of seeing the d's go by ...

    Code:
    <body>
    <div id="box"> </div>
    <input type="button" value="stop!" onclick = "clearTimeout(t)">
    </body>
    <script>
    function human2(toDisplay2){
       (function inner(){	
    	var toAdd = toDisplay2.substring(0,1);
    	t = setTimeout(inner , 500);
    	document.getElementById('box').innerHTML += toAdd;})()
    			}
    			human2("dsd"); 
    </script>

  • #5
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,536
    Thanks
    80
    Thanked 4,490 Times in 4,454 Posts
    And not to quibble--because Davey's code works--I would always add in var t = null; outside of any function both to ensure that the variable really *is* global and to give myself a convenient way to test to see if any timeout is active.
    Code:
    <body>
    <div id="box"> </div>
    <input type="button" value="stop!" onclick = "if ( t != null ) { clearTimeout(t); t = null; }">
    </body>
    <script>
    var t = null;
    function human2(toDisplay2){
       (function inner(){	
    	var toAdd = toDisplay2.substring(0,1);
    	t = setTimeout(inner , 500);
    	document.getElementById('box').innerHTML += toAdd;})()
    			}
    			human2("dsd"); 
    </script>
    My code there adds nothing at all to the functionality in this particular example. But that technique can be useful in other circumstances.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #6
    Gütkodierer
    Join Date
    Apr 2009
    Posts
    2,127
    Thanks
    1
    Thanked 426 Times in 424 Posts
    I feel the need to clear things up a bit, since the replies are a bit beside the point.

    Quote Originally Posted by Old Pedant View Post
    You have to code that this way:
    Code:
    	function human2(toDisplay2){
    		var toAdd = toDisplay2.substring(0,1);
    		setTimeout("human2('" + toDisplay2 + "')" , 500);
    		document.getElementById('box').innerHTML += toAdd;
    	}
    	human2("dsd");
    The main problem with the original code is that it puts code into a string, instead of a function (which would create a closure, and all would be fine). While this approach here does work, it isn't really a solution; suppose the function human2 doesn't expect a string parameter but an array or an object — now what are you going to do? Convert the parameter to a JSON string in order to be able to put it into the code string? That's just silly.

    Generally speaking — never put code into a string. If you do, you're entering a world of hurt (and undebuggability).


    Quote Originally Posted by DaveyErwin View Post
    Here is another way ...

    Code:
    <body>
    <div id="box"> </div>
    </body>
    <script>
    function human2(toDisplay2){
          (function inner(){	
    	var toAdd = toDisplay2.substring(0,1);
    	setTimeout(inner , 500);
    	document.getElementById('box').innerHTML += toAdd;})()
    			}
    			human2("dsd"); 
    </script>
    this way toDisplay2 continues to exist.
    That's the right idea, but it's a bit convoluted and makes the whole closure thing look more complicated than it really is.

    Creating a closure in order to pass that local variable as a parameter is as easy as this:
    PHP Code:
    function human2(toDisplay2) {
        var 
    toAdd toDisplay2.substring(0,1);
        
    document.getElementById('box').innerHTML += toAdd;
        
    setTimeout(function () {human2(toDisplay2);} , 500);

    There's no need for a named inner function.

  • Users who have thanked venegal for this post:

    DaveyErwin (09-09-2011)


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •