Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have a setTimeout inside a handler of another setTimeout?

Here's a quick (broke) jsfiddle: http://jsfiddle.net/wH2qF/

This isn't working for some reason... is it because I have a setTimeout inside a handler of another setTimeout?

$(function() {
   $("#Volume").click(function() {
      setTimeout(triggerVolumeChange, 4000);
      function triggerVolumeChange() 
      {
          var volumeDiv = document.getElementById("volumeNumber");
          var volumeOld = 8;
          var volumeNew = 37;
          var timeNew = (1000/(volumeNew-volumeOld));
          changeVolume();
                        
          function changeVolume()
          {
             volumeDiv.innerHTML = volumeOld;
             volumeOld++;
             if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
          };
      });
});

Should specify that for clarity purposes I deleted other things from that Click function, and also to clarify what doesn't work exactly, well, basically, I click and nothing happens, whereas if I cut out this chunk of code it works fine... actually the setting of the vars also work fine (naturally I presume) but when I paste or uncomment the changeVolume() function then the click stops working again... Any thoughts?

--

Another piece of clarification: What I'm trying to do is, on click, simulate the volume going from value 8 to 37, in a string.. thus the setTimeout inside that function.

--

As per your guy's request, here's the entire code... I doubt it will make sense, but here it is... FYI, on click this will trigger a number of animations to simulate the flow of an application I'm designing..

<script>
            $(function() {
                $("#Volume").click(function() {
                                        
                    var userPrompt = document.getElementById("userPrompt")
                    userPrompt.innerHTML = "Change volume to 37";
                                        
                    var avatarIcon = document.getElementById("avatarIcon");
                    avatarIcon.innerHTML = "<img src='imgs/haloIcons-volume_82x76.png' alt='Volume'/>";
                
                    var hints = document.getElementById("hints");
                    hints.style.opacity = 0;
                    $(".dragonTvOut").toggleClass("dragonTvIn");
                    
                    setTimeout(triggerP, 1000);
                    function triggerP()
                    {
                        var halo = document.getElementById('avatar');
                        if( 'process' in halo ) { 
                            halo.process();
                        };
                    };
                    
                    setTimeout(triggerUserPrompt, 2000);
                    function triggerUserPrompt() 
                    {
                        document.getElementById("userPrompt").className = "userPromptIn";
                    };
                    
                    setTimeout(triggerVolumeChange, 4000);
                    function triggerVolumeChange() 
                    {
                        document.getElementById("userPrompt").className = "userPromptEnd";
                        
                        var halo = document.getElementById('avatar');
                        if( 'resume' in halo ) { 
                            halo.resume();
                        }

                        document.getElementById("avatarIcon").className = "avatarIconEnd";
                        
                        var volumeDiv = document.getElementById("volumeNumber");
                        var volumeOld = 8;
                        var volumeNew = 37;
                        var timeNew = (1000/(volumeNew-volumeOld));
                        changeVolume();
                        
                        function changeVolume()
                        {
                            volumeDiv.innerHTML = volumeOld;
                            volumeOld++;
                            if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
                        }​;
                        
                        var side = 100;
                        var paper = new Raphael(volumeArcAnim, 100, 300);
                        
                        paper.customAttributes.arc = function (xloc, yloc, value, total, R) {

                            var alpha = 360 / total * value,
                                a = (90 - alpha) * Math.PI / 180,
                                x = xloc + R * Math.cos(a),
                                y = yloc - R * Math.sin(a),
                                path;
                            if (total == value) {
                                path = [
                                    ["M", xloc, yloc - R],
                                    ["A", R, R, 0, 1, 1, xloc - 0.01, yloc - R]
                                ];
                            } else {
                                path = [
                                    ["M", xloc, yloc - R],
                                    ["A", R, R, 0, +(alpha > 180), 1, x, y]
                                ];
                            }
                            return {
                                path: path
                            };
                        };
                    
                        var arcWidth = 87;
                        var strokeRadius = arcWidth/2;
                        
                        var indicatorArc = paper.path().attr({
                            "stroke": "#ffffff",
                            "stroke-width": 3,
                            arc: [side/2, side/2, 12, 100, strokeRadius]
                        });
                        
                        indicatorArc.animate({
                            arc: [side/2, side/2, 60, 100, strokeRadius]
                        }, 1500, "<>", function(){
                            // anim complete here
                        });
                        
                    };
                                            
                });
            });
            </script>
like image 331
ttothec Avatar asked Dec 14 '12 22:12

ttothec


Video Answer


2 Answers

Yes, you can have a setTimeout() inside another one -- this is the typical mechanism used for repeating timed events.

The reason yours isn't working is not to do with the setTimeout() itself; it's to do with the way you've nested the functions.

The changeVolume() function being inside triggerVolumeChange() means that you can't reference it directly using its name.

The quickest solution for you would be to remove the nesting, so that changeVolume() is at the root level rather than nested inside triggerVolumeChange().

like image 174
Spudley Avatar answered Sep 17 '22 23:09

Spudley


You're missing an }:

$(function() {
   $("#Volume").click(function() {
      setTimeout(triggerVolumeChange, 4000);
      function triggerVolumeChange()
      {
          var volumeDiv = document.getElementById("volumeNumber");
          var volumeOld = 8;
          var volumeNew = 37;
          var timeNew = (1000/(volumeNew-volumeOld));
          changeVolume();

          function changeVolume()
          {
             volumeDiv.innerHTML = volumeOld;
             volumeOld++;
                 if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
          };
      } // that one was missing
   });
});
like image 44
Sirko Avatar answered Sep 17 '22 23:09

Sirko