jQuery find () работает только один раз для результата AJAX? - PullRequest
3 голосов
/ 31 июля 2009

все я новичок в jQuery, и у меня возникла небольшая проблема с манипулированием результатами AJAX с помощью методов jQuery.

Я использую AJAX get и выполняю метод find для полученного результата. Но, похоже, это работает только один раз. Последующие попытки использовать тот же селектор в аргументе find() не работают. Различные селекторы будут работать, но опять же только один раз.

Кажется, что-то происходит при обходе результата AJAX?

AJAX call ...

    $.get('sections.htm', {}, function(data) {
        var $response = $('<div />').html(data);
        showContent("teaser");

        function showContent(nav) {
            loadContent(nav);
            loadSlimboxHack();
            $('#content').fadeIn(400);
        }

Найти элемент ...

    function loadContent(nav) {
        if (nav == 'teaser')
        {
            $('#content').html($response.find('.teaser'));
        }

Это работает, но если я снова попробую showContent(".teaser"), это не удастся, потому что кажется, что он ничего не находит и поэтому #content перезаписывается ни с чем.

Взгляните на мой сайт, чтобы увидеть ...

http://www.shadowshapes.com/dev

Ответы [ 4 ]

3 голосов
/ 01 августа 2009

@ RedSquare, Спасибо большое! Это поставило меня на правильный путь.

Для непосвященных append() действует как «перемещение» вместо «копирования» в контексте одного селектора. Очевидно, это распространенная ошибка среди новичков. И это не совсем задокументировано? Теперь мне не так плохо! :)

http://www.nabble.com/Undocumented-move-copy-behavior-of-append%28%29-et-al.-ts21179461s27240.html#a24146606

Так что мне нужно было использовать clone() в дополнение к append() в этом случае.

$('#content').append($response.find('div.concept' + tag).clone());

Отлично! Проблема решена!

2 голосов
/ 01 августа 2009

Вы используете содержимое $ response и добавляете некоторые из них в другие элементы. Это означает, что они переезжают из $ response в свой новый дом, поэтому селектор сработает только один раз.

Посмотри на это так. Если вы возьмете из своего кошелька только один-единственный доллар и положите его в мой, в следующий раз, когда вы заглянете в свой кошелек, его там не будет. Зачем? Потому что он у меня.

0 голосов
/ 01 августа 2009

Спасибо, на самом деле я уже пытался обойти $response без удачи. Я попробовал это снова, а также попробовал ваше другое предложение сделать $response глобальным. Не повезло.

Самое странное, что $response доступно в loadContent(). Просто кажется, что как только селектор найден, его уже нельзя «использовать»? Например, после загрузки страницы происходит следующее ...

        if (nav == 'teaser')
        {
            $('#content').html($response.find('.teaser'));
        }

Но затем нажатие на одно из изображений тизера инициирует событие ...

    $('div.teaser_img').live("click", function() {
        var nav = $(this).attr("id");
        $('#content').fadeOut(400, function() {
            showContent(nav, $response);
        });

Который затем запускает условное внутри loadContent() ...

                if (nav == projects[i])
                {
                    var tag = '#' + nav;
                    $('#content').html($response.find('div.teaser' + tag));
                    $('#content').append($response.find('div.concept' + tag));
                    break;
                }

Так как div.teaser уже был найден при загрузке страницы, #content записывается только с div.concept. Любой из других селекторов также будет работать, если он еще не использовался.

0 голосов
/ 31 июля 2009

С первого взгляда: Я думаю у вас закрытие проблемы ...

Переменная $response не фиксируется в области закрытия для обработчиков событий (например, по вашему щелчку -> fadeout -> showContent). Я предполагаю, что это будет исправлено, если вы передадите переменную $response вместо того, чтобы пытаться ссылаться на нее глобально. То есть на вашем примере сделайте что-то вроде этого:

$.get('sections.htm', {}, function(data) {
    var $response = $('<div />').html(data);
    showContent("teaser", $response);

    function showContent(nav, $response) {
        loadContent(nav, $response);
        loadSlimboxHack();
        $('#content').fadeIn(400);
    }
...
    function loadContent(nav, $response) {
    if (nav == 'teaser')
    {
        $('#content').html($response.find('.teaser'));
    }
...

Таким образом, вы гарантируете, что $response всегда будет рядом, когда вы будете его использовать. Другой вариант - сделать $response действительно глобальным, объявив его за пределами $(document).ready.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...