Закрытие Javascript при привязке к событию ведет себя по-разному.

Я пытаюсь использовать закрытие, чтобы функция могла выполняться только один раз. Звучит просто, но работает это так:

function runOnce(fn)  // returns copy of fn which can only execute once
{
    var ran = false;

    return function() 
    {
        if (!ran)
        {
            fn();
            ran = true;
        }
    };
}

Я тестировал функцию так:

function lazyLoadGrid(event, ui)
{
    alert('hi');
}

var test1 = runOnce(lazyLoadGrid);
var test2 = runOnce(lazyLoadGrid);

test1();
test2();

test1();
test2();

И она работает, как ожидалось - «привет» получает предупреждение ровно дважды.

Но затем я пытаюсь использовать runOnce (lazyLoadGrid) в качестве обратного вызова для события пользовательского интерфейса jQuery:

$('.accordion').each(function() 
{ 
    $(this).accordion({ autoHeight: false, change: runOnce(lazyLoadGrid) });
});

И наступает безумие. Я ожидаю, что каждый «аккордеон» на странице будет запускать lazyLoadGrid () ровно один раз при первом открытии этого аккордеона. Вместо этого обратные вызовы закрытия, похоже, ведут себя так, как если бы все они ссылались на одну и ту же копию 'ran'. lazyLoadGrid () запускается в первый раз, когда я открываю любой аккордеон, и никогда больше не запускается для любого другого аккордеона. Регистрация значения предварительного условия «run» показывает, что оно «истинно» каждый раз, когда я щелкаю любой аккордеон после первого.

Какое объяснение этому? Возможно, стоит отметить, что у меня есть нечетная страница с вложенными аккордеонами и несколькими вкладками пользовательского интерфейса jQuery, каждая из которых содержит аккордеоны. Что еще хуже, когда я переключаю вкладки, закрытие действительно выполняется на первом открытом аккордеоне любой данной вкладки. Любой совет очень ценится.

12
задан sacheie 29 February 2012 в 23:55
поделиться