Как обойти замыкание в jQuery?

Рейтинг: 1Ответов: 1Опубликовано: 09.02.2015

Добрый день.

Столкнулась впервые с понятием замыкания в jQuery и не могу его обойти.

Замыкание происходит в функции reward:

     $(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);

   });

Функция reward вызывается при клике на определенную фигуру на странице. Все решения, найденные в сети, не сработали.

Спасибо.

Обновление

Проблема в том, что при данном коде levels всегда равняется 11 (т.е. максимальной величине messages.length). А должна быть итерация со значением от 0 до 11. Причина такого поведения кода в замыкании JS/Jquery. Я пробовала переписать код, чтоб была нужная мне итерация, однако не меняется.

Обновление

@Zelta, спасибо за разъяснения. В общем, сработало таким образом

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

Так и не поняла, почему в for цикл срабатывает сразу, а не пошагово.

Ответы

▲ 2Принят

Еще раз повторю.

Во-первых, замыкание — это, грубо говоря, функция в функции. Я никак не могу понять, причем оно тут.

Во-вторых, давайте внимательно посмотрим на ваш цикл. На каждом шаге цикла вы в контейнер #text кладете messages[levels], в контейнер #next_level'Next Level: ' + levels. Естественно, когда цикл отработает полностью, в #text окажется messages[11], а в #next_level11 (да, кстати, в массиве messages всего 11 элементов, а поскольку нумерация начинается с нуля, правильно поставить строгое условие на окончание цикла).

Теперь поместим строку console.log(levels); в тело цикла. При нажатии .ball в консоли можно наблюдать такую картину:

ForLoop console output

Очевидно, цикл отработал полностью (убедитесь сами).

Теперь, внимание, вопрос: а что вы хотите добиться, 11 раз перезаписывая значение #text и #next_level? Мне лично кажется, что здесь что-то не так, и «замыкания» тут уж явно ни при чем.