Я искал все, где и я работал над этим часами. В принципе, у меня есть выбор Ajax для извлечения данных с веб-страницы, которая извлекает данные из базы данных. Этот код предназначен для слайд-шоу для галереи изображений. Вся функция показана ниже, однако часть, которая не работает должным образом, это две строки кода, которые получают высоту и ширину изображений.Проблема с синхронизацией AJAX с jQuery
Изображения принимаются правильно, и они отображаются в порядке (ну не совсем, но они появляются). Строки, которые запрашивают ширину и высоту изображений, возвращают 0 больше всего того времени. Вероятность того, что они вернут правильные значения, составляет 5%. Это приводит к тому, что оператор if сразу после этого всегда оценивает значение false, что делает широкие изображения за пределами края веб-страницы.
Эта проблема присутствует только в браузерах, основанных на Webkit. У браузеров, основанных на Gecko, нет этой проблемы.
Я думаю, проблема в том, что jQuery пытается запросить изображения до того, как вызов Ajax завершил свой запрос. Есть ли способ заставить jQuery ждать завершения Ajax с его запросом?
function LoadForm() {
GalleryDataSource = new kendo.data.DataSource({
transport: {
read: {
url: BaseAPI + "/PhotosByAlbum2",
dataType: "json",
data: { "location": locationID, "ID": $.getQuery('ID') }
}
}
});
$("#slides").kendoListView({
dataSource: GalleryDataSource,
template: kendo.template($("#SlidesTemplate").html())
});
$.ajax({
type: "Get",
contentType: "application/json; charset=utf-8",
url: BaseAPI + "/PhotosByAlbum2",
datatype: "json",
data: { "location": locationID, "ID": $.getQuery('ID') },
success: function (d) {
for (var i = 0; i < d.length; i++) {
$('#Show').append(
'<figure><img src="' + d[i].Path +
'" id="' + d[i].ID +
'"/><figcaption>Title: ' + d[i].Title + '<br />' +
'Description: ' + d[i].Description +
'</figcaption></figure>'
);
/*these do*/ var imgheight = $("#" + d[i].ID).height();
/*not work*/ var imgwidth = $("#" + d[i].ID).width();
if (imgheight < "768" && imgwidth > imgheight) {
$("#" + d[i].ID).addClass("wideimage");
} else {
$("#" + d[i].ID).addClass("tallimage");
}
}
$('#Show').innerfade({
animationtype: 'fade',
speed: 1050,
timeout: 2000,
type: 'sequence',
containerheight: '500px'
});
}
});
$('#back').click(function() {
window.location = 'Photos.aspx'
});
}
Примечание: Я попытался с помощью $.when(*ajax call here*).done(function() {*do stuff*});
. Он вел себя точно так же.
И я пробовал установить опцию async
на значение false. Такое же поведение.
Я также попытался добавить обработчик события complete
в вызов Ajax. Опять же, он вел себя одинаково.
Если вы хотите использовать размеры изображения в расчете, вы не сможете запустить этот код до тех пор, пока изображения не будут успешно загружены. И единственный способ узнать, когда это произошло, - использовать обработчик 'onload' для самих изображений. Если ваш код сейчас работает, то это ТОЛЬКО, потому что изображения находятся в кеше браузера. Ваш код не будет работать в любом браузере, если изображения не были в кеше браузера. – jfriend00
Изображения хранятся на сервере, и этот код извлекает их через Ajax и, при успешном выполнении, отображает их. Не имеет смысла, почему этот код работает 100% времени в браузерах Gecko и менее 5% времени в браузерах Webkit. –
Это имеет смысл для меня. Вы НЕ извлекаете изображения самостоятельно через ajax. Вы получаете имена файлов изображений через AJAX. Затем вы создаете теги изображений, устанавливаете '.src', и браузер должен THEN загружать изображения. Вы пытаетесь затем НЕМЕДЛЕННО ссылаться на высоту и ширину. Если кешировать, некоторые браузеры быстро сделают изображения, а некоторые - нет. Если вы не кешировали, ни один браузер не будет иметь изображения. Ваш код просто написан неправильно. Вы не можете надежно получить доступ к высоте или ширине, пока тег '' не обработает обработчик 'onload', чтобы указать, что изображение теперь успешно загружено. – jfriend00