jQuery — показать список после его загрузки

#jquery #json #load #show

#jquery #json #загрузить #показать

Вопрос:

Я создал скрипт для получения дочерних жанров из «родительского» жанра из базы данных MySQL, используя getJSON() . Чтобы показать список дочерних жанров, я использовал show() функцию, но поскольку список еще не загружен, он просто появится, и мне это не нравится. Как мне использовать load() функцию (или любую другую, которая поможет в моем случае), чтобы дождаться загрузки списка, а затем использовать show() ?

 function getZvrsti(id){
        $.getJSON('test.php?parent=' id, function(data) {
            var tmpLi;
            $.each(data, function(id, name) {
                tmpLi = $('<li><input type="checkbox" value="' name['id'] '" id="zvrstId' name['id'] '" /> <label for="zvrstId"' name['id'] '">' name['name'] '</label></li>');
                $(".drugeZvrsti").append(tmpLi);
                tmpLi = "";
            });
        });
    }
  

Это функция, которая использует getJSON , и вот фрагмент, в котором я использую show() :

 $(".naprejZvrst").click(function(){
            if(!on2){
                parent = $(this).attr("id");
                getZvrsti(parent);
                $(".drugeZvrsti").load(function(){ //my poor example of load()
                    druga.show(400);
                });
                on2 = true;

            }
            else if(on2){
                druga.hide(400);
                on2 = false;
                $(".drugeZvrsti").html(''); 
            }

        })
  

Класс drugeZvrsti — это <ul> список, в котором отображается список, var druga это a <div> , где находится весь <ul> список.
ПРИМЕЧАНИЕ: я нашел пример load() функции, но никто не объяснил, как использовать список, большинство из них были для изображений.

Ответ №1:

$.getJSON который является сокращением для $.ajax is по умолчанию асинхронный, что означает, что выполнение кода продолжится после того, как вы его вызовете.

Что вы хотите сделать, это показать список в обратном вызове после того, как вы создали и добавили элементы списка.

 // Let's define our local scope variables
var druga = $(".drugeZvrsti"),
    request = false;

function getZvrsti(id) {
    // Save the request to our requests object
    requests[id] = $.getJSON('test.php?parent=' id, function(data) {
        var html = "";
        $.each(data, function(id, name) {
            html  = '<li><input type="checkbox" value="' name['id'] '" id="zvrstId' name['id'] '" /> <label for="zvrstId"' name['id'] '">' name['name'] '</label></li>';
        });
        // Append the list items and then fade in
        druga.append(html).show(400);
        // We no longer have a request going
        request = false;
    });
}

$(".naprejZvrst").click(function(){
    var id = $(this).attr("id");
    // Since we don't want multiple requests, abort any existing one
    if (request) {
        request.abort();
        request = false;
    }
    if (druga.is(":hidden")) {
        getZvrsti(id);
    } else {
        // Stop any animations, fade out and
        // use callback to empty the list when its hidden
        druga.stop().hide(400, function(){
            druga.empty();
        });
    }
});
  

Вы также можете отметить некоторые другие изменения, которые я сделал здесь, такие как:

  • Кэширование селектора для списка, поскольку он использовался несколько раз
  • Создайте список в виде простой строки и добавьте его один раз. Это связано с тем, что манипулирование DOM происходит медленно, поэтому рекомендуется свести это к минимуму.
  • Сохранение запроса в переменную, чтобы при наличии какого-либо текущего запроса его можно было прервать, когда список скрыт
  • Проверка видимости druga с .is помощью вместо использования переменной on2

Комментарии:

1. Отличный скрипт! Теперь почти все работает нормально! Теперь только одна проблема: если я покажу druga, скрою его и попытаюсь показать его снова, ничего не появится, что беспокоит.

2. Неважно, что мой сценарий был немного другим, теперь все исправлено. Спасибо!

Ответ №2:

Если вы добавите функцию обратного вызова, которая будет выполняться после getJSON успешного завершения, вы сможете увидеть, когда она завершится. Хотя я только что создал druga show, вам нужно будет изменить это, чтобы установить переменную, которую вы затем проверите в своем событии click. Все это есть в документах.

 function successFunction(data) {
  druga.show(400);
}

function getZvrsti(id){
        $.getJSON('test.php?parent=' id, function(data) {
            var tmpLi;
            $.each(data, function(id, name) {
                tmpLi = $('<li><input type="checkbox" value="' name['id'] '" id="zvrstId' name['id'] '" /> <label for="zvrstId"' name['id'] '">' name['name'] '</label></li>');
                $(".drugeZvrsti").append(tmpLi);
                tmpLi = "";
            });
        }, successFunction(i));
    }
  

Комментарии:

1. @MarcusEkwall — я не тестировал его, просто сделал это, чтобы указать OP в правильном направлении. Есть ли у вас какие-либо отзывы о том, почему это не сработает?

2. Вы обновили свой код, но он по-прежнему неверен. $.each не принимает обратный вызов. Кроме того, вы не передаете его в качестве аргумента, а фактически его результат. Как вы можете видеть, обратный вызов уже есть, поэтому на самом деле нет необходимости добавлять второй, и если вам действительно нужно, правильным способом было бы добавить a .done(successFunction) к $.getJSON вызову.

3. Хорошо, как я уже сказал, я на самом деле не тестировал его — я не вижу упоминания .done() в документах.

4. @medmondson jqXHR объект, возвращаемый с помощью $.getJSON , реализует поведение обещания . Я предлагаю, чтобы использование .done since .success устарело в 1.7 .

Ответ №3:

вы могли бы использовать обратный вызов, подобный этому:

 function getZvrsti(id, callback){
    $.getJSON('test.php?parent=' id, callback(data));
}
  

  getZvrsti(parent, function(data) {
        var tmpLi;

        $.each(data, function(id, name) {
            tmpLi = $('<li><input type="checkbox" value="' name['id'] '" id="zvrstId' name['id'] '" /> <label for="zvrstId"' name['id'] '">' name['name'] '</label></li>');
            $(".drugeZvrsti").append(tmpLi);
            tmpLi = "";
        });

       druga.show(400);
 });
  

непроверенный код