#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);
});
непроверенный код