Good day.

Faced the concept of closure in jQuery for the first time and can't get around it.

The closure occurs in the reward function:

$(document).ready(function () { var messages = [ "Nice Job!", "Excellent clickin'!", "That was Awesome!", "Man are you good!", "Boom!", "You're a pro!", "Unbelievable!", "Insanity!", "You're on fire!", "That was crazy!", "You are blowin' my mind!" ] var levels = 0; reward = function() { $('.ball-container').css('display','none'); $('.message_container').css('position', 'relative'); for(levels = 0; levels <= messages.length; levels++){ $('#text').css('visibility','visible').html(messages[levels]); $('#next_level').css('visibility','visible').html('Next Level: ' + levels); } window.setTimeout(hideText, 2000) }; hideText = function() { $('.message_container').css('position', 'absolute'); $('#text').css('visibility','hidden'); $('#next_level').css('visibility','hidden'); $('.ball-container').css('display','block'); $('.ball').click(reward); }; $('.ball').click(reward); }); 

The reward function is called when clicking on a certain shape on the page. All solutions found on the network did not work.

Thank.

Update

The problem is that with this code, the levels always equals 11 (that is, the maximum value of messages.length). And there should be an iteration with a value from 0 to 11. The reason for this behavior of the code is in the closure of JS / Jquery. I tried to rewrite the code so that the iteration I needed was, but it does not change.

Update

@Zelta , thanks for the clarification. In general, it worked this way.

  $(document).ready(function (){ var messages = [ "Nice Job!", "Excellent clickin'!", "That was Awesome!" ] var levels = 0; $('.ball').click(function(){ if(levels <11){ flashMessage(); flashMessage = function() { var message = messages[levels]; $('#text').text(message); levels+=1; $('#level').text(levels+1); }; 

I didn’t understand why the for cycle works immediately and not step by step.

  • @ number1985, Try to write more detailed questions. Explain what you see the problem, what it means "I can not get around it"? - Boris
  • The problem is that with this code, the levels always equals 11 (that is, the maximum value of messages.length). And there should be an iteration with a value from 0 to 11. The reason for this behavior of the code is in the closure of JS / Jquery. I tried to rewrite the code so that the iteration I needed was, but it does not change. - number1985 February
  • @ number1985 you have the levels variable as a global one, so it is overridden somewhere in another function. Add a var in front of the variable. - lampa
  • First, do not confuse js and jquery. Secondly, are you sure that closure is what you think about? Thirdly, how did you determine that levels always equals 11? Put a debug print there. If it really always equals 11, it is very strange. Please provide more code? - Zelta
  • Give the content of the messages - ReinRaus

1 answer 1

I repeat.

First, a closure is, roughly speaking, a function in a function. I just can not understand where it is.

Second, let's take a close look at your cycle. At each step of the cycle, you put messages[levels] in the #text container, in the #next_level container - 'Next Level: ' + levels . Naturally, when the cycle has completed completely, there will be messages[11] in #text , and messages[11] in #next_level (yes, by the way, there are only 11 elements in the messages array, and since the numbering starts from zero, set the strict condition to end the cycle correctly).

Now put the line console.log(levels); in the loop body. When you click .ball in the console, you can observe the following picture:

ForLoop console output

Obviously, the cycle has worked completely ( see for yourself ).

Now, attention, the question: what do you want to achieve by overwriting the value of #text and #next_level 11 times? It seems to me personally that there is something wrong here, and the “closures” here have nothing to do with it.

  • one
    An article about closures to eliminate confusion: habrahabr.ru/post/38642 - Zelta
  • Messages from the loop should appear in turn after clicking on the shape. How here jenniferdewalt.com/bouncing_ball.html . Those. My cycle works and constantly issues 11. And it should be 1, 2, 3, etc. Well, the data from the cycle in turn. The habrahabr.ru/post/38642 article has a similar example for (var i = 0; i <links.length; i ++) {links [i] .onclick = function () {alert (i); }} Which for the correct work rewrote for (var i = 0; i <links.length; i ++) {(function (i) {links [i] .onclick = function () {alert (i);}}) (i ); }. - number1985
  • I understood what you want to do. To be honest, I'm too lazy to rewrite my post again. Take a piece of paper and write line by line what makes your code after pressing a button. Normally it looks like this: jsfiddle.net/2z5rhvLL/2 - Zelta