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 9 of 9
  1. #1
    New to the CF scene
    Join Date
    Mar 2012
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Calling a method every second...

    So I'm new around here, and to web dev in general, but I've got a (hopefully) short question.

    I am trying to call a function (nextMonth()) every second from the time that the cycle method gets called, until it is called again. As of now I am trying to use setInterval, (and I previously tried with setTimeout and using a callback argument but maybe I wasn't doing that properly).

    The problem is that after running the cycle() method for 5 or 6 seconds, the entire browser freezes up and you have to kill it and restart it.

    Here is my code as of now:

    Code:
    function cycle()
    {
    	if(CYCLEINT != null) //STOP THE CYCLE LOOP
    	{
    		window.clearInterval(CYCLEINT);
    		CYCLEINT = null;
    		document.getElementById("cycle").innerHTML = "Cycle Months";
    	} 
    
    	else //LOOP IS NOT RUNNING, INITIATE AND CONTINUE INTERVAL.
    	{
    		CYCLEINT = self.setInterval("nextMonth()", 1000);				
    		document.getElementById("cycle").innerHTML = "Pause";
    	}
    } 
    
    
    function prevMonth()
    {
    	var dVal = $( ".slider" ).slider( "option", "value");
    
    	if(dVal > 1)
    	{
    		dVal--;
    		$( ".slider" ).slider( "option", "value", dVal );
    		refresh();
    	}
    }
    
    function nextMonth()
    {
    	var dVal = $( ".slider" ).slider( "option", "value");
    
    	if(dVal < dateMax)
    	{
    		dVal++;
    		$( ".slider" ).slider( "option", "value", dVal );
    		refresh();
    	}
    
    	if(CYCLEINT != null && dVal >= dateMax)		
    	{
    		cycle();
    	}
    }

  • #2
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,335
    Thanks
    11
    Thanked 588 Times in 569 Posts
    remove
    Code:
    	if(CYCLEINT != null && dVal >= dateMax)		
    	{
    		cycle();
    	}
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • #3
    New to the CF scene
    Join Date
    Mar 2012
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    That if-statement there checks to make sure there is still room on the end of the slider bar and that the date value can be incremented.

    Without that the loop will never end.

  • #4
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,335
    Thanks
    11
    Thanked 588 Times in 569 Posts
    Quote Originally Posted by DaveRich View Post
    That if-statement there checks to make sure there is still room on the end of the slider bar and that the date value can be incremented.

    Without that the loop will never end.
    well with it, it will never stop spawning new loops...
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • #5
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,043
    Thanks
    0
    Thanked 251 Times in 247 Posts
    You have two loops running. Replace setInterval with setTimeout.

    And also don't pass string to the setTimeout/setInterval. Pass a function pointer instead.

    Code:
    setTimeout(nextMonth, 1000);
    If you have parameter to the function, then it should be:

    Code:
    setTimeout(function(){ nextMonth(param1, param2); }, 1000);

  • #6
    New to the CF scene
    Join Date
    Mar 2012
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I tried using setTimeout instead, but what happens is it looks like nothing is working and then the slider is all of a sudden at the end.

    Would it be possibly to split the "cycle" method into two seperate methods? and then change the method call similar to how you change innerHTML?

  • #7
    Regular Coder
    Join Date
    Apr 2005
    Location
    Texas
    Posts
    448
    Thanks
    24
    Thanked 63 Times in 63 Posts
    Here's a real simple loop constructor that comes in handy for these cases, there's not much in the way of error detection, but I like it.
    Code:
        var Loop =  function(myFunct){
    
            var loop = this;
            
            var rate = 1000 ,
                code = myFunct ,
                paused = false,
            
                run = function () {
    
                    clearTimeout(loop.Cycle);
    
                    if (code) {
    
                        if(!paused)
                            code();
    
                        loop.Cycle = setTimeout(run , rate);
    
                    }
    
                };
                
            loop['resume'] = function () {
                paused = false;
            } ,
                
            loop['pause'] = function () {
                paused = true;
            } ,
                
            loop['kill'] = function () {
                code = false;
            } ,
                
            loop['speed'] = function (r) {
                (r&&(typeof r=='number')&&r>0)&&(rate = r);
                return rate;
            } ,
                
            loop['init'] = function () {
                if(!loop.Cycle&&code)
                    run();
            };
        };
    /* Minified for your convenience ;)
    var Loop=function(f){function e(){clearTimeout(a.a);b&&(c||b(),a.a=setTimeout(e,d))}var a=this,d=1E3,b=f,c=!1;a.resume=function(){c=!1};a.pause=function(){c=!0};a.kill=function(){b=!1};a.speed=function(a){a&&"number"==typeof a&&0<a&&(d=a);return d};a.init=function(){!a.a&&b&&e()}};
    */
    I whipped up the following test page for you to familiarize yourself with the function:
    Code:
    <div id="red" style="position:absolute;top:20px;left:20px;border:1px solid red;padding:20px">
     <button onclick="red.init()">init</button>
     <button onclick="red.pause()">pause</button>
     <button onclick="red.resume()">resume</button>
     <button onclick="red.speed(red.speed()+500)">slower</button>
     <button onclick="red.speed(red.speed()-500)">faster</button>
     <button onclick="red.kill();this.innerHTML='dead';">kill</button>
     <br>
     <h1>Red</h1>
    </div>
    <div id="blue" style="position:absolute;top:20px;left:400px;border:1px solid blue;padding:20px">
     <button onclick="blue.init()">init</button>
     <button onclick="blue.pause()">pause</button>
     <button onclick="blue.resume()">resume</button>
     <button onclick="blue.speed(blue.speed()+500)">slower</button>
     <button onclick="blue.speed(blue.speed()-100)">faster</button>
     <button onclick="blue.kill();this.innerHTML='dead';">kill</button>
     <br>
     <h1>Blue</h1>
    </div>
    <script>
        var Loop=function(f){function e(){clearTimeout(a.a);b&&(c||b(),a.a=setTimeout(e,d))}var a=this,d=1E3,b=f,c=!1;a.resume=function(){c=!1};a.pause=function(){c=!0};a.kill=function(){b=!1};a.speed=function(a){a&&"number"==typeof a&&0<a&&(d=a);return d};a.init=function(){!a.a&&b&&e()}};
    
        var red_code = function(){
            document.getElementById('red').innerHTML+='<br>looped ' + red.speed()
        }
        var blue_code = function(){
            document.getElementById('blue').innerHTML+='<br>looped ' + blue.speed()
        }
    
        var red = new Loop(red_code);
        red.speed(5000);
    
        var blue = new Loop(blue_code);
        blue.speed(1000);
    
    </script>
    So if I understand your algorithm (and I'm not sure I do) you would do the following
    Code:
    var Loop=function(f){function e(){clearTimeout(a.a);b&&(c||b(),a.a=setTimeout(e,d))}var a=this,d=1E3,b=f,c=!1;a.resume=function(){c=!1};a.pause=function(){c=!0};a.kill=function(){b=!1};a.speed=function(a){a&&"number"==typeof a&&0<a&&(d=a);return d};a.init=function(){!a.a&&b&&e()}};
    
    function cycle(){
    	
    	if(CYCLEINT != null) //STOP THE CYCLE LOOP
    	{
    		CYCLEINT = null;
    		nextMonthCycle.pause();
    		document.getElementById("cycle").innerHTML = "Cycle Months";
    	} 
    
    	else //LOOP IS NOT RUNNING, INITIATE AND CONTINUE INTERVAL.
    	{
    		CYCLEINT = 'somevalue';  //Not sure if you need this anymore...
    		nextMonthCycle.resume();
    		document.getElementById("cycle").innerHTML = "Pause";
    	}
    
    };
    
    function prevMonth()
    {
    	var dVal = $( ".slider" ).slider( "option", "value");
    
    	if(dVal > 1)
    	{
    		dVal--;
    		$( ".slider" ).slider( "option", "value", dVal );
    		refresh();
    	}
    }
    var nextMonthCycle;
    function nextMonth()
    {
    	nextMonthCycle = new Loop(function()
    	{
    		var dVal = $( ".slider" ).slider( "option", "value");
    
    		if(dVal < dateMax)
    		{
    			dVal++;
    			$( ".slider" ).slider( "option", "value", dVal );
    			refresh();
    		}
    
    		if(CYCLEINT != null && dVal >= dateMax)		
    		{
    			cycle();  //you can call this as many times as you want, and it won't spawn a new loop
    		}
    	});
    	nextMonthCycle.init();
    }
    I'm not really sure if I integrated it properly with your code... If I could see more of the code...

    Either way- you don't want to enable the chance for a loop to be called from within itself, that is what is crashing your browser. The Loop constructor only allows a loop to be created once, preventing any accidental loop feedback logic. From there you can pause and resume at will.
    Allwisend bin ich nicht, doch viel ist mir bewursst
    -Goethe

  • #8
    New to the CF scene
    Join Date
    Mar 2012
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Thanks blaze4218,

    I had to make a few changes to get the code to run, for example I kept getting the following error:

    nextMonthCycle is not defined in the current scope.

    I think this was because the variable doesn't get defined until the nextMonth() function was called, so calling cycle() first calls it to fail.

    So in order to fix this I just added the following two lines of code just above the declaration for nextMonth so they get executed on page load.

    Code:
    nextMonth();
    nextMonthCycle.pause();
    That seems to work, however the browser still freezes and crashes when it runs the loop.

    Here is a link to the source for the entire page: http://jsfiddle.net/Xh8ZU/
    Last edited by DaveRich; 03-14-2012 at 06:56 PM. Reason: Added link to source.

  • #9
    New to the CF scene
    Join Date
    Mar 2012
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I found out a solution to this problem, as it turns out the loop wasn't the problem, the problem was the jQuery package (qTip) that I was using for tooltips.

    I just had to make sure that the qTip's weren't updating content while the loop was running, as it was queuing all the qTip updates until the loop finished and then try and update everything at once.

    Works now.

    Thanks for all your help!


  •  

    Posting Permissions

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