load
событие изображения вызывается, когда он загружен (DOH!), И критически, если не подключить обработчик до он загружается, ваш обработчик не будет вызван. Браузеры будут загружать ресурсы параллельно, поэтому вы не можете быть уверены (даже в событии jQuery ready
, в котором указано, что DOM страницы готов), что изображение еще не загружено при запуске вашего кода.
Вы можете использовать complete
свойство объекта изображения, чтобы узнать, является ли это уже было загружено это, так:
var firstPhoto = $("#photos img:first");
if (firstPhoto[0].complete) {
// Already loaded, call the handler directly
handler();
}
else {
// Not loaded yet, register the handler
firstPhoto.load(handler);
}
function handler() {
alert("Image loaded!");
}
Там может быть даже состояние гонки в том, что, если браузер в вопросе действительно реализует мульти- где загрузка изображения может происходить в другом потоке, чем поток Javascript.
Конечно, если ваш селектор будет соответствовать нескольким изображениям, вам нужно будет это обработать; ваш селектор выглядит он должен соответствовать только один, так что ...
Редактировать Эта версия позволяет для нескольких изображений, и я думаю, что он обрабатывает любые условия без Javascript гонки (и, конечно, в настоящее время там не никаких условий Javascript гонки, сам Javascript является однопоточным в браузерах [если не использовать новый материал web workers]):
function onImageReady(selector, handler) {
var list;
// If given a string, use it as a selector; else use what we're given
list = typeof selector === 'string' ? $(selector) : selector;
// Hook up each image individually
list.each(function(index, element) {
if (element.complete) {
// Already loaded, fire the handler (asynchronously)
setTimeout(function() {
fireHandler.call(element);
}, 0); // Won't really be 0, but close
}
else {
// Hook up the handler
$(element).bind('load', fireHandler);
}
});
function fireHandler(event) {
// Unbind us if we were bound
$(this).unbind('load', fireHandler);
// Call the handler
handler.call(this);
}
}
// Usage:
onImageReady("#photos img:first");
Несколько примечаний:
- Обратный вызов не получает объект
event
; вы можете изменить его, чтобы сделать это, если хотите, но, конечно, не было бы события в случае, когда изображение уже загружено, поэтому оно будет иметь ограниченную полезность.
- Возможно, вы использовали
one
вместо bind
и unbind
, но мне нравится ясность, и я параноик.:-)
Aha, гений. Большое спасибо. Я собираюсь уйти и посмотреть разницу между ними :) – JasonS
У вас есть ссылка на событие 'ready' ** изображений **? Единственный «готовый», о котором я знаю, - это событие JQuery «DOM is ready», которое совершенно другое. –
Не совсем, я использовал пробную версию и ошибку с большим изображением. – ThiefMaster