开发者

javascript scope issue in recursive function

开发者 https://www.devze.com 2023-04-10 16:39 出处:网络
In code below, I expect variable counter to incement by 1 on each repetition, but it remains zero. var count = 0;

In code below, I expect variable counter to incement by 1 on each repetition, but it remains zero.

var count = 0;
var marqueeText = new Array("Some text goes here",
                            "A bit more verbose text goes here.",
                            "Some more verbose <a href='xxx'>text</a> goes <a href='xxx'>here</a> with some <a href='xxx'>links</a>."
                            );

开发者_运维百科function fnShowMarquee(count){  
// console.log(count + "-" + marqueeText.length );
        if (count > marqueeText.length){
            count = 0;      
        }
        else{           
            count++;
        }
        $('#marquee_box span').html(marqueeText[count]);

            // do some stuff, then wait 4 seconds and call function again

        setTimeout ("fnShowMarquee(count)", 4000);
}


$(document).ready(function() {
    fnShowMarquee(0);
});


The problem is you are using a global count then creating a new local in fnShowMarquee

Try this instead:

var count = 0;

//...

function fnShowMarquee(){  
    //...
    setTimeout (fnShowMarquee, 4000);
}

$(document).ready(function() {
    fnShowMarquee();
});

EDIT:- From RobG's comment:

$(document).ready(function() {
    var count = 0;
    //...

    function fnShowMarquee(){ ... }
    fnShowMarquee();
});

by putting it all in the ready function the count variable cannot be accessed by other code and it will not mess around in the window global scope.


Further to James' answer, keep count and marqueeText in closures so they can't be messed around by other code:

var fnShowMarquee = (function() {
    var count = 0;
    var marqueeText = [
       "Some text goes here",
       "A bit more verbose text goes here.",
       "Some more verbose <a href='xxx'>text</a>" + 
       " goes <a href='xxx'>here</a> with some <a href='xxx'>links</a>."
    ];
    // ...                           

    return function() {  
        //...
        setTimeout (fnShowMarquee, 4000);
    }
}());


I'd try using count explicitly:

setTimeout (function() { fnShowMarquee(count); }, 4000);


Made a few changes to your code:

  1. You are using a global count variable. You don't need to pass it in the parameters.
  2. The if condition should be count == marqueeText.length - 1. In your previous code, marqueeText[count] was going off the bounds.
  3. $('#marquee_box span') wasn't working for me. So I changed it to $('span#marquee_box')

Your code should be:

var count = 0;
var marqueeText = new Array("Some text goes here",
                            "A bit more verbose text goes here.",
                            "Some more verbose <a href='xxx'>text</a> goes <a href='xxx'>here</a> with some <a href='xxx'>links</a>."
                            );

function fnShowMarquee(){  
  console.log(count + "-" + marqueeText.length );
  if (count == marqueeText.length - 1){
      count = 0;      
  }
  else{           
      count++;
  }
  $('span#marquee_box').html(marqueeText[count]);

      // do some stuff, then wait 4 seconds and call function again

  setTimeout ("fnShowMarquee()", 4000);
}


$(document).ready(function() {
    fnShowMarquee();
});


You are increasing the parameter variable count. Not the global one. And the setTimeout like that uses the global one, because it runs your function on document scope.

Try to call your function as just

function fnShowMarquee()

or do it like

setTimeout (function() { fnShowMarquee(count); }, 4000);
0

精彩评论

暂无评论...
验证码 换一张
取 消