Слушатель событий JavaScript / jQuery при загрузке изображений для всех браузеров - PullRequest
21 голосов
/ 16 сентября 2011

Я ищу способ реализовать это для максимально возможного количества браузеров:

var image = new Image();
image.addEventListener("load", function() {
                               alert("loaded");
}, false);
image.src = "image_url.jpg";

Это не сработало в IE, поэтому я погуглил и обнаружил, что IE ниже 9 не поддерживает .addEventListener().Я знаю, что есть эквивалент jQuery под названием .bind(), но он не работает на Image().Что мне нужно изменить, чтобы это работало и в IE?

Ответы [ 5 ]

29 голосов
/ 16 сентября 2011

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 изображения установлено значение тот же источник, что и раньше
  • Не правильно всплывает дерево DOM
  • Может перестать срабатывать для изображений, которые уже живут в браузере кэш

См. jQuery документы для получения дополнительной информации.

7 голосов
/ 16 сентября 2011

Вы должны использовать .attachEvent() вместо .addEventListener().

if (image.addEventListener) {
  image.addEventListener('load', function() {
       /* do stuff */ 
  });
} else {
  // it's IE!
  image.attachEvent('onload', function() {
    /* do stuff */
  });
}
3 голосов
/ 16 сентября 2011

new Image в основном возвращает тег <img>, поэтому вы можете кодировать в jQuery, например: http://jsfiddle.net/pimvdb/LAuUR/1/.

$("<img>", { src: '...' })
    .bind('load', function() {
        alert('yay');
    });

РЕДАКТИРОВАТЬ: в случае загрузки действительных изображений

$('.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() {
  });

});
2 голосов
/ 16 сентября 2011

Вы можете использовать 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); }
        }
    };
}
1 голос
/ 12 января 2013

Лучшим способом сделать это сейчас, вероятно, является использование jQuery и плагина jQuery imagesLoaded вместо встроенного в JQuery load() или обычного JS.Плагин заботится о различных особенностях браузера, на которые ссылается документация jQuery, а именно о кэшированных изображениях и повторном запуске обратного вызова, если новое изображение src совпадает.Просто скачайте jquery.imagesloaded.min.js , добавьте его с <script src="jquery.imagesloaded.min.js"></script> и все готово:

$(image).imagesLoaded(function() {
    alert("loaded");
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...