JavaScript/jQuery прослушиватель событий при загрузке изображений для всех браузеров
Я ищу способ реализовать это для максимально возможного количества браузеров:
var image = new Image();
image.addEventListener("load", function() {
alert("loaded");
}, false);
image.src = "image_url.jpg";
Это не работает в IE, поэтому я googled и узнал, что IE ниже 9 не поддерживает .addEventListener()
. Я знаю, что есть эквивалент jQuery, называемый .bind()
, но это не работает на Image()
. Что мне нужно изменить, чтобы это тоже работало в IE?
Ответы
Ответ 1
IE поддерживает attachEvent.
image.attachEvent("onload", function() {
// ...
});
С помощью jQuery вы можете просто написать
$(image).load(function() {
// ...
});
Когда дело доходит до событий, если у вас есть возможность использовать jQuery, я бы предложил использовать его, потому что он позаботится о совместимости браузера. Ваш код будет работать на всех основных браузерах, и вам не о чем беспокоиться.
Обратите внимание, что для того, чтобы событие загрузки запускалось в IE, вам нужно убедиться, что изображение не будет загружено из кеша, иначе IE не будет запускать событие загрузки.
Чтобы сделать это, вы можете добавить фиктивную переменную в конце URL-адреса вашего изображения, например
image.setAttribute( 'src', image.getAttribute('src') + '?v=' + Math.random() );
Некоторые известные проблемы, использующие метод загрузки jQuery, это
Предостережения о событии загрузки при использовании с изображениями
Общая проблема разработчиков пытается решить с помощью .load() ярлык должен выполнять функцию, когда изображение (или коллекция изображения) полностью загружены. Существует несколько известных оговорок с это следует отметить. Это:
- Он не работает последовательно и не надежно, кросс-браузер
- В WebKit он не срабатывает корректно, если для изображения src установлено значение тот же src, что и раньше
- Неправильно выворачивает дерево DOM
- Может перестать запускаться для изображений, которые уже живут в браузере. кэш
Подробнее см. jQuery для более подробной информации.
Ответ 2
Вы должны использовать .attachEvent()
, а не .addEventListener()
.
if (image.addEventListener) {
image.addEventListener('load', function() {
/* do stuff */
});
} else {
// it IE!
image.attachEvent('onload', function() {
/* do stuff */
});
}
Ответ 3
new Image
в основном возвращает тег <img>
, поэтому вы можете кодировать в jQuery, например: http://jsfiddle.net/pimvdb/LAuUR/1/.
$("<img>", { src: '...' })
.bind('load', function() {
alert('yay');
});
EDIT: в случае загрузки действительных изображений
$('.buttons').html('');
var range = [];
for (var i = 1; i <=50; i++) range.push(i);
range.forEach(function(i) {
var img_src = 'http://i.imgur.com/' + i + '.jpg';
var $img = $("<img>", {
src: img_src
});
$img.on('load', function() {
$('.buttons').append($img);
});
$img.on('error', function() {
});
});
Ответ 4
Вы можете использовать attachEvent
, но я предпочел бы, чтобы вы добавили addEventListener
. Вот код на этой ссылке MDN для добавления слушателя событий:
if (!Element.prototype.addEventListener) {
var oListeners = {};
function runListeners(oEvent) {
if (!oEvent) { oEvent = window.event; }
for (var iLstId = 0, iElId = 0, oEvtListeners = oListeners[oEvent.type]; iElId < oEvtListeners.aEls.length; iElId++) {
if (oEvtListeners.aEls[iElId] === this) {
for (iLstId; iLstId < oEvtListeners.aEvts[iElId].length; iLstId++) { oEvtListeners.aEvts[iElId][iLstId].call(this, oEvent); }
break;
}
}
}
Element.prototype.addEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
if (oListeners.hasOwnProperty(sEventType)) {
var oEvtListeners = oListeners[sEventType];
for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
}
if (nElIdx === -1) {
oEvtListeners.aEls.push(this);
oEvtListeners.aEvts.push([fListener]);
this["on" + sEventType] = runListeners;
} else {
var aElListeners = oEvtListeners.aEvts[nElIdx];
if (this["on" + sEventType] !== runListeners) {
aElListeners.splice(0);
this["on" + sEventType] = runListeners;
}
for (var iLstId = 0; iLstId < aElListeners.length; iLstId++) {
if (aElListeners[iLstId] === fListener) { return; }
}
aElListeners.push(fListener);
}
} else {
oListeners[sEventType] = { aEls: [this], aEvts: [ [fListener] ] };
this["on" + sEventType] = runListeners;
}
};
Element.prototype.removeEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
if (!oListeners.hasOwnProperty(sEventType)) { return; }
var oEvtListeners = oListeners[sEventType];
for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
}
if (nElIdx === -1) { return; }
for (var iLstId = 0, aElListeners = oEvtListeners.aEvts[nElIdx]; iLstId < aElListeners.length; iLstId++) {
if (aElListeners[iLstId] === fListener) { aElListeners.splice(iLstId, 1); }
}
};
}
Ответ 5
Лучший способ сделать это сейчас - это, вероятно, использовать jQuery и плагин jQuery imagesLoaded вместо встроенного jQuery load()
или простой JS. Плагин заботится о различных видах браузера, к которым относятся документы jQuery, а именно о кэшированных изображениях и повторном обратном вызове, если новое изображение src
совпадает. Просто скачайте jquery.imagesloaded.min.js, добавьте его с помощью <script src="jquery.imagesloaded.min.js"></script>
, и вам будет хорошо:
$(image).imagesLoaded(function() {
alert("loaded");
});