JQuery рекурсия - PullRequest
       11

JQuery рекурсия

0 голосов
/ 08 июля 2011

У меня проблема с моим кодом, какой-то код не работает, когда я вызываю рекурсивный вызов одной и той же функции внутри него.Это должно быть что-то с myGalleria = Galleria.get(0);, но я не знаю, как заставить все это работать.

Document Ready (просто чтобы показать, когда я вызываю функцию в первый раз, все работает в первый раз)

$(document).ready(function(){
    $.getJSON('getImages.php', {
        cat: "123"
    }, function(imgData){
        createGallery(imgData);
    });
});

Теперь сама функция, обратите внимание, что когда я нажимаю на .galleria-menuButtons span, который вызывает ту же функцию, ничего не работает, ну, само galleria создает, но больше ничего.имеет аналогичную функцию для window.resize, и она также не работает после рекурсивного вызова.

$(window).resize(function(){
    $(".galleria-container").css("width", $(window).width());
    $(".galleria-container").css("height", $(window).height());
    galleriaRescale = Galleria.get(0);
    galleriaRescale.rescale(); // <- this is not working either
    //sizeBG();
});

1 Ответ

3 голосов
/ 08 июля 2011

FYI - это на самом деле не рекурсия в традиционном смысле, потому что вы вызываете createGallery из обработчика щелчков, который запускает JSON-запрос, который затем вызывает createGallery, когда это удается, оба из которых произойдут после предыдущего вызов createGallery заканчивается.

Но у вас есть выживающие закрытия функций, которые могут сбивать с толку или вызывать проблемы. Одно из предположений состоит в том, что вы можете убедиться, что вещи, которые вы ожидаете, являются локальными переменными (например, myGalleria, перед ними стоит var, так что они действительно являются локальными переменными, а не переменными, которые могут быть ограничены до более высокого уровня и быть под влиянием предыдущего воплощения этого вызова или влиять на более ранний вызов, который еще не завершен.

var myGalleria = Galleria.get(0);

Затем, предполагая, что imgData является некоторой структурой данных, такой как массив или объект, вы должны убедиться, что существует только одна глобальная версия этой структуры данных, которая никогда не изменяется, или что каждый вызов createGallery имеет соответствующая отдельная копия этой структуры данных. Если по ходу дела что-то меняется, то последующие вызовы createGallery могут не получить нужные данные. Если это структура данных только для чтения (вы не меняете ее), то вы, вероятно, в порядке с ней.

Хорошо, давайте поговорим о псевдокоде, чтобы узнать, что это делает.

  1. На странице готово, вы получите некоторые данные изображения JSON.
  2. Когда это удается, вы звоните createGallery с этими данными изображения.
  3. вызов createGallery выполняет какую-то операцию в DOM (возможно, анимацию)
  4. Затем он вызывает: myGalleria = Galleria.get(0); Поскольку перед myGalleria нет переменной var, это объявление глобальной переменной (плохие новости для рекурсии и замыканий)
  5. Затем вы используете структуру данных myGalleria для внесения некоторых изменений в DOM (добавление меню и пунктов меню).
  6. Затем вы добавляете обработчик щелчков .live к довольно универсальному набору классов CSS (возможно, вы добавили этот обработчик щелчков здесь несколько раз).
  7. Затем вы снова получаете данные изображения JSON.
  8. Когда эти данные изображения извлекаются, вы начинаете весь процесс заново, вызывая createGallery.

Резюме

Две потенциальные проблемы, которые я вижу, состоят в том, что myGalleria не является локальной переменной и, вероятно, должно быть, и вы, возможно, добавляете дублирующие обработчики щелчков.

Если ни один из них полностью не решит проблему, то нам, вероятно, понадобится дополнительная информация о том, что делает Galleria.get(0).

К вашему сведению, изменение размера clickHandler выглядит так, как будто у него может быть та же проблема, если не использовать var, чтобы сделать объявление переменной локальной переменной.

Раунд 2

Хорошо, вот еще несколько замечаний.

  1. Когда вы добавляете меню и кнопки меню с этим блоком кода, вы не предоставляете никаких уникальных идентификаторов для функций addElement или appendChild (вы предоставляете "menu" и "menuButtons" для обоих) , Таким образом, я не знаю, как вы можете однозначно подключиться к ним в последующем событии щелчка. Насколько ваш код выглядит, все пункты меню выглядят одинаково, и ни один из них не имеет уникального состояния. Я не знаю кода Galleria, но я предполагаю, что кто-то должен создать уникальные идентификаторы для этих новых элементов, чтобы вы могли однозначно идентифицировать их в своем последующем обработчике кликов.

    // Adding menu and menu buttons myGalleria.addElement("menu").appendChild("container", "menu"); myGalleria.addElement("menuButtons").appendChild("menu", "menuButtons");

  2. Когда вы устанавливаете обработчик щелчков, чтобы предположительно обрабатывать щелчки только для этих пунктов меню, вы каждый раз используете один и тот же селектор CSS, поэтому нет никакого способа, которым этот обработчик щелчков будет уникально назначен только вновь создаваемые пункты меню (что, я полагаю, вам нужно). Я не знаю кода Galleria, но я предполагаю, что вы должны создать какой-то уникальный идентификатор, который вы передаете в addElement и appendChild для вновь созданных пунктов меню, а затем ссылаетесь на этот уникальный идентификатор при установке обработчика щелчка. Аналогичным образом, эта функция должна быть нацелена только на те кнопки меню, которые вы создали с помощью уникальных идентификаторов myGalleria.$("menuButtons").html(data);

  3. Наконец, я бы посоветовал вам изменить имя одной из ваших переменных, чтобы избежать путаницы. В вашем обработчике кликов измените три вхождения imgData на data, чтобы не было путаницы с замыканиями и значением imgData.

Раунд 3

В конечном счете, одним из исправлений было (встроено в комментарии):

Я думаю, что это может сработать, если вы просто устанавливаете обработчик щелчков .live один раз за пределами функции createGallery, а не вызываете его каждый раз. Поскольку это .live, он будет автоматически работать для всех будущих кнопок, которые вы создадите, поэтому вы должны вызывать его только один раз. Я бы предложил поместить его в функциональный блок $ (document) .ready.

...