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 12 of 12
  1. #1
    New to the CF scene
    Join Date
    Sep 2006
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Question Help with window.setTimeout

    Here is my code:

    <script>
    var confirmationPageURL = "http://google.com";

    // Add handler for Ecwid's OnPageLoad event
    if (
    typeof(Ecwid) == 'object'
    && typeof(Ecwid.OnPageLoad) == 'object'
    ) {
    Ecwid.OnPageLoad.add(function(page) {
    // Redirect user if needed
    if (
    typeof(page) == 'object'
    && 'ORDER_CONFIRMATION' == page.type
    ) {
    window.location = confirmationPageURL;
    window.setTimeout(confirmationPageURL, 8000, true);
    }
    });
    }

    </script>
    I'm just doing a simple redirect after a purchase is made from a shopping cart I use on my site. However, I can't get the window.setTimeout working. The page is instantly redirected and not 8 seconds. I'm sure I have wrong syntax or placement. Who knows. I know nothing about JS. Any help is appreciated.

    Thank you

  • #2
    Master Coder felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    6,642
    Thanks
    0
    Thanked 649 Times in 639 Posts
    The first parameter of setTimeout MUST be a function, not a string.

    Code:
    var confirmationPageURL = "http://google.com";
    
     // Add handler for Ecwid's OnPageLoad event
     if (
     typeof(Ecwid) == 'object'
     && typeof(Ecwid.OnPageLoad) == 'object'
     ) {
     Ecwid.OnPageLoad.add(function(page) {
     // Redirect user if needed
     if (
     typeof(page) == 'object'
     && 'ORDER_CONFIRMATION' == page.type
     ) {
     doit = function() {window.location = confirmationPageURL;}
     window.setTimeout(doit, 8000, true);
     }
     });
     }
    Stephen
    Learn Modern JavaScript - http://javascriptexample.net/
    Helping others to solve their computer problem at http://www.felgall.com/

    Don't forget to start your JavaScript code with "use strict"; which makes it easier to find errors in your code.

  • #3
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,068
    Thanks
    0
    Thanked 256 Times in 252 Posts
    Quote Originally Posted by felgall View Post
    The first parameter of setTimeout MUST be a function, not a string.
    Can also be a string and doesn't have to be a function. Can be any valid Javascript expression.
    Code:
    <script>
    function clickMe(){
        setTimeout("document.getElementById('log').innerHTML+='click,'", 1000);
        setTimeout("logIt()", 2000);
        setTimeout(logIt, 3000);
        setTimeout(function(){document.getElementById('log').innerHTML+='click,'}, 4000);
    }
    function logIt(){
       document.getElementById('log').innerHTML+='click,';
    }
    </script>
    <button type="button" onclick="clickMe()">click me</button>
    <span id="log"></span>
    Though of course, using function pointer or anonymous function is the most efficient of them all.
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #4
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    18,079
    Thanks
    203
    Thanked 2,542 Times in 2,520 Posts
    I believe that the string parameter

    setTimeout("logIt()", 2000);

    was required to overcome some bug in early versions of IE. It is the equivalent of the hated inefficient eval. It is worth pointing out that nowadays there is no need to use anything other than

    setTimeout(logIt, 3000);

    Which I think is felgall's point.

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • #5
    Master Coder felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    6,642
    Thanks
    0
    Thanked 649 Times in 639 Posts
    Quote Originally Posted by glenngv View Post
    Can also be a string and doesn't have to be a function. Can be any valid Javascript expression.
    If it isn't a function then the browser effectively wraps it in an eval() in order to convert it ti a function.

    You ought to try reading the standards. They specify that it has to be a function. It is only because JavaScript is loosely typed that you can put something other than a function there and have JavaScript convert it to a function automatically.

    If you enter

    Code:
    setTimeout('doSomething()',5000);
    then JavaScript effectively reads that as

    Code:
    setTimeout(function() {eval('doSomething()')},5000);
    even IE5 didn't have the bug Philip M refers to (I don 't have a copy of IE4 to check but I don;t remember it having the bug either so the bug was specific to IE3). So unless you still have a ton of IE3 users amongst your visitors there is no need to force all the other browsers to do that type conversion.

    Any type conversion that you force the browser to do for you makes the code less efficient by a small amount. While each is only a very small difference they all add up.

    It is only because JavaScript will convert whatever you place as the first parameter into a function that it will work if you put a string there instead.
    Stephen
    Learn Modern JavaScript - http://javascriptexample.net/
    Helping others to solve their computer problem at http://www.felgall.com/

    Don't forget to start your JavaScript code with "use strict"; which makes it easier to find errors in your code.

  • #6
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    18,079
    Thanks
    203
    Thanked 2,542 Times in 2,520 Posts
    http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

    In versions earlier than Microsoft Internet Explorer 5, the first argument of setTimeout must be a string. Evaluation of the string is deferred until the specified interval elapses.

    As of Internet Explorer 5, the first argument of setTimeout can be a string or a function pointer.

    But of course while IE4 still existed it was necessary to use the string syntax even in new web pages for backwards compatibility. There are many other examples of this which is why HTML5 will take time to get a hold. I see that even today IE6 is still used, albeit by less than 1% of users.

    Bearing in mind that browsers are free, why do people not download the latest versions right away? Is it something to do with memory on old computers?
    Last edited by Philip M; 04-15-2012 at 04:03 PM.

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • #7
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,068
    Thanks
    0
    Thanked 256 Times in 252 Posts
    I didn't advocate to use string in setTimeout. I know that eval is evil. In fact I said at the end of my post that using function pointer is the way to go. I merely corrected the statement:
    The first parameter of setTimeout MUST be a function, not a string.
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #8
    Master Coder felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    6,642
    Thanks
    0
    Thanked 649 Times in 639 Posts
    Quote Originally Posted by glenngv View Post
    I didn't advocate to use string in setTimeout. I know that eval is evil. In fact I said at the end of my post that using function pointer is the way to go. I merely corrected the statement:
    My statement was correct and didn't need correcting - the first parameter MUST be a function in JavaScript. If you enter a string then JavaScript will convert that string into a function in order to be able to use it. You can get away with specifying a string as the first parameter only because JavaScript is loosely typed and will convert that string into a function for you.

    Internet Explorer 8 and earlier do not run JavaScript at all and instead run a different but similar language called jScript. It is only the antiquated versions of jScript used by IE3 and IE4 where that value had to be a string and those disappeared even before Netscape 4 did and JavaScript itself has changed completely since then. Once IE8 disappears we will be able to forget about jScript completely and start using the correct <script type="application/javascript"> when attaching scripts instead of the text/javascript which is obsolete but still needs to be used to allow the script to run as jScript in old versions of IE that don't support JavaScript.

    The first parameter to setTimeout MUST be a function. If you enter anything except a function then JavaScript will convert what you supply into a function. Since the conversion will run an implicit eval() this means that the result may be different depending on whether or not you are runing the JavaScript in strict mode since strict mode treats eval calls differently.
    Last edited by felgall; 04-15-2012 at 10:15 PM.
    Stephen
    Learn Modern JavaScript - http://javascriptexample.net/
    Helping others to solve their computer problem at http://www.felgall.com/

    Don't forget to start your JavaScript code with "use strict"; which makes it easier to find errors in your code.

  • #9
    Regular Coder
    Join Date
    Aug 2010
    Posts
    974
    Thanks
    19
    Thanked 212 Times in 210 Posts
    Code:
    <script> 
    a = 10;
    setTimeout("a=4",3)
     
    </script>
    <button onclick="alert(a)"></button>
    maybe its converted to

    (function(){return a=4})()
    Last edited by DaveyErwin; 04-15-2012 at 11:08 PM.

  • #10
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,068
    Thanks
    0
    Thanked 256 Times in 252 Posts
    Quote Originally Posted by felgall View Post
    If you enter

    Code:
    setTimeout('doSomething()',5000);
    then JavaScript effectively reads that as

    Code:
    setTimeout(function() {eval('doSomething()')},5000);
    Are you 100% sure that the above statement is correct?

    Shouldn't JavaScript read that internally as this instead?

    Code:
    setTimeout(eval('doSomething()'), 5000);
    When the parameter passed to the setTimeout is a JavaScript expression in string format, JavaScript effectively uses eval() to evaluate the code but I don't think it has to convert that to a function pointer. It doesn't have to.

    Again, I don't advocate to use string in setTimeout, I don't use it myself. I just don't believe how you generalized that the parameter "MUST be a function and not a string". Last time I checked, the setTimeout syntax says the first parameter is a JavaScript expression or function. And it doesn't say or even imply that if an expression is passed, it will convert that to a function pointer.

    http://www.devguru.com/technologies/...ettimeout.html
    http://www.w3schools.com/jsref/met_win_settimeout.asp
    http://www.pagecolumn.com/javascript/settimeout.htm
    Last edited by glenngv; 04-16-2012 at 12:02 PM.
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #11
    New to the CF scene
    Join Date
    Sep 2006
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Excellent advise from everyone - thank you so much for your help. The 1st answer felgall gave worked perfect. Tested in IE8-9, Firefix, Chrome, Safari - all worked. Thank you again guys for your lively discussion and education (since I'm a total newb on JS).

  • #12
    Master Coder felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    6,642
    Thanks
    0
    Thanked 649 Times in 639 Posts
    Quote Originally Posted by glenngv View Post
    Are you 100% sure that the above statement is correct?

    Shouldn't JavaScript read that internally as this instead?

    Code:
    setTimeout(eval('doSomething()'), 5000);
    When the parameter passed to the setTimeout is a JavaScript expression in string format, JavaScript effectively uses eval() to evaluate the code but I don't think it has to convert that to a function pointer. It doesn't have to.
    Even if an expression is allowed, specifying the expression as a string still requires that it be converted from a string to an expression if you don't actually enter the parameter as an expression (and I haven't seen anyone actually enter an expression as the parameter - the professionals all seem to use functions while the novices use strings).

    It doesn't matter exactly which equivalent that JavaScript is using for the conversion - the important point is that JavaScript has to convert what is entered into a function (or an expression) if you don't specify the correct data type in the first place and that conversion will take time. Even if an expression is valid as the first parameter as an alternative to a function, a string is not and needs to be converted into either an expression or function in order to be run.

    An alternative way you could hard code your conversion to a function to make it more obvious that such a conversion needs to take place would be:

    Code:
    setTimeout(new Function('doSomething()'), 5000);
    that is an alternative way that JavaScript could convert the string into a function.

    Which of the alternatives JavaScript actually uses doesn't matter. The important point is that JavaScript needs that first parameter to be a function (or expression) and so if you don't specify a function then JavaScript will need to convert what you do specify into one. The simplest way to do that keeping the overhead to a minimum would be

    Code:
    setTimeout(doSomething, 5000);
    which avoids the need for JavaScript to do any conversion at all and which is therefore the more efficient way to do it.

    Any implicit type conversions that you can eliminate by changing your code to provide the right type in the first place will make your script run fractionally faster. Even if you don't consider the time difference to be significant enough to worry about you still end up with less to actually type in when you do it correctly rather than having to type the extra characters to specify a string for JavaScript to convert back into a function than what you have to type to simply enter the function in the first place. Why type extra in order to give JavaScript a string to convert into a function when simply specifying the function that JavaScript expects involves less typing.

    Specifying the wrong data type where you have control over the data type and can easily specify the right one is one of the indications that the person who wrote the code is a novice programmer with little understanding of the language. It doesn't make much difference with a single setTimeout but specifying incorrect data types and forcing JavaScript to convert them for you would make a more significant difference to run times with intermediate level JavaScript applications.
    Last edited by felgall; 04-16-2012 at 10:34 PM.
    Stephen
    Learn Modern JavaScript - http://javascriptexample.net/
    Helping others to solve their computer problem at http://www.felgall.com/

    Don't forget to start your JavaScript code with "use strict"; which makes it easier to find errors in your code.


  •  

    Posting Permissions

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