Can I set setTimeout inside another setTimeout?

Here's the quick (broken) jsfiddle: http://jsfiddle.net/wH2qF/

This does not work for some reason ... is it because I have setTimeout inside 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); }; }); }); 

It should be noted that for clarity, I removed other things from this Click function, and also to find out what does not work exactly, well, basically, I click and nothing happens, whereas if I cut out this piece of code, it works fine ... actually setting up the wars also works fine (naturally, I suppose), but when I insert or uncomment the changeVolume () function, then the click stops working again ... Any thoughts?

-

Another part of the explanation: what I'm trying to do is click, simulate a volume going from a value of 8 to 37 on a line .. thus setTimeout inside this function.

-

According to your boyfriendโ€™s request, all the code is here ... I doubt it will make sense, but here it is ... FYI, when clicked, it will trigger several animations to simulate the application flow. m design ..

 <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> 
+6
source share
4 answers

In your broken example http://jsfiddle.net/wH2qF/ there are several problems

  • You forgot to specify jsfiddle to use jQuery
  • The volume range identifier (in JS) was ph , but should be volumeNumber (as in HTML)

Click here to see the working version.

If you selected jQuery from libraries in jsfiddle, you would see an error

Uncaught TypeError: Unable to set 'innerHTML' property from null

This makes me think that your jsfiddle is not a good representation of your problem. Maybe try creating another shortcut, because the one you added only had "stupid" errors?

+3
source

You are missing } :

 $(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 }); }); 
+2
source

Yes, you can have setTimeout() inside another - this is a typical mechanism used to repeat time events.

The reason yours is not working is not related to setTimeout() ; this is due to how you nested the functions.

The changeVolume() function inside triggerVolumeChange() means you cannot reference it directly using its name.

The quickest solution for you is to remove the nesting, so changeVolume() is at the root level, and not nested inside triggerVolumeChange() .

+1
source

If you do not want to use setInterval() , you can make the code work with these changes:

 $(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)); var changeVolume = function () { volumeDiv.innerHTML = volumeOld; volumeOld++; if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew); }; changeVolume(); } }); }); 

Working demo on jsFiddle .

0
source

All Articles