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 4 of 4
  1. #1
    New to the CF scene
    Join Date
    Jul 2009
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Angry pass arg to function by value.

    ok I have a unique problem, I need to pass a variable's value to a function instead of a pointer (reference) to the variable as by the time the function is called (because of the SetTimeout function) the variables value has changed.

    I realise that may not be so clear so I've included the long explanation below, please bare with me ... =p

    I have a 2 dimensional menu, when you hover over menu item it animates. to exaggerate that it is a menu (from the design it's not immediatly apparent) I decided to add a simple animation for when the page loads where it loops through each menu item and animates it in sequence.

    each of the sub menu items are stored in a 2D array (SubMenuItemsArray) and I get the "wave" effect by having a short (60 millisecond) pause between each animation (achieved with Window.SetTimeout).

    heres the code, I've set i and j to 0 after the loop to highlight the issue.

    for(var i = 0; i < SubMenuItemsArray.length; i++)
    {
    for(var j = 0; j < SubMenuItemsArray[i].length; j++)
    {
    setTimeout(function()
    {
    animateSubMenuItem( SubMenuItemsArray[i][j]);
    }, (j*60));
    }
    }
    i = 0;
    j = 0;

    now, the issue, by the time SetTimeout runs the animation code i and j have already been set to 0. And it therefore calls:
    animateSubMenuItem( SubMenuItemsArray[0][0]);
    20 times, animating the first sub menu item ... 20 times and none of the others.

    this happens because the function isn't called until (j * 60) milliseconds have passed and i and j are passed to the function by reference, whereas I need to pass only the value of i and j if the function is to work.

    is there a way to do that? or a simple work around that anyone can think of? I'm working on a work around but at the moment it isn't too elegant =p.

    Thanks for any help
    Dead.Rabit

  • #2
    New to the CF scene
    Join Date
    Jul 2009
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts
    not entirely sure why, (i'm not complaining) but putting quotes around everything and removing the function part seems to make it work (not entirely sure of the difference it makes, I thaught the two ways of writing it were one and the same)


    this is the corrected code:

    setTimeout("animateSubMenuItem( SubMenuItemsArray[" + i + "][" + j + "])", (j*60));

    sorry for the clutter,
    D.R

  • #3
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    I personally highly dislike using strings when you can do without them.

    Code:
    for (var i = 0; i < SubMenuItemsArray.length; i++) {
      for (var j = 0; j < SubMenuItemsArray[i].length; j++) {
        setTimeout ((function (i, j) {
          return function () {
            animateSubMenuItem (SubMenuItemsArray[i][j]);
          };
        }) (i, j), j * 60);
      }
    }
    Trinithis

  • #4
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,448
    Thanks
    11
    Thanked 598 Times in 578 Posts
    i prefer [].map to loops:

    Code:
    SubMenuItemsArray.map(function(row){
    	row.map(function(cell, n){
    		setTimeout(function(){
    		    animateSubMenuItem( cell );
    		}, n * 60 );
    	});
    	
    });
    To me, it looks cleaner.
    Array.map also lets you re-use loop code elsewhere and avoids the problem encountered by the OP by providing a private scope that loops just don't have.

    well not yet anyway, though i am working on a library that provides block and loop scope...
    my site (updated 2014/10/20)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.3, IE11:9.2, IE9:2.7, IE10:2.6, FF:16.8, CH:47.5, SF:7.8, NON-MOUSE:37%


  •  

    Posting Permissions

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