bxSlider и недогруженные картинки

В версии BxSlider v4.1.2 имеется досадный баг (или фича), который делал мне нервы. Все дело в том, что bxSlider на столько хорош, что умеет делать предварительную загрузку изображений (и даже содержимого iframe) перед тем, как начнет свою полноценную работу. И вот тут то и кроется эта самая фича ака баг.

В настройках при инициализации слайдера можно указать preloadImages в двух вариантах: all и visible (значение по умолчанию), т.е. сказать слайдеру предзагружать все или только те изображания, что попадают в “видимые” слайды.
Каждый раз, когда стартует bxSlider, исполняется функция setup, которая в себе вызывает loadElements(preloadSelector, start);, ту самую функцию для предварительной загрузки изображений.

Вторым параметром в нее передается имя функции обратного вызова (callback):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var loadElements = function(selector, callback){
var total = selector.find('img, iframe').length;
if (total == 0){
callback();
return;
}
var count = 0;
selector.find('img, iframe').each(function(){
$(this).one('load', function() {
if(++count == total) callback();
}).each(function() {
if(this.complete) $(this).load();
});
});
}

Все просто: найти все изображения и iframe и слушать событие load (onload), и когда все ресурсы будут загружены - вызвать callback. Отличный план!

Но, так получилось, что в проекте появились картинки, которых нет. Т.е. тег img есть, у него есть src, который указывает на несуществующую картинку (сервер отдает 404 ошибку).

Таким образом, событие load срабатывало не для всех изображений и функция start никогда не вызывалась. Слайдер инициализировался, но не полностью. Частично работал в режиме infiniteLoop: false, мог листать слайды вперед. Как следствие, функция onSliderLoad никогда не вызывалась.

Проблема решается одной строкой, даже не строкой, а добавлением слушателя на событие error:

1
2
3
4
5
6
7
selector.find('img, iframe').each(function(){
$(this).one('load error', function() {
if(++count == total) callback();
}).each(function() {
if(this.complete) $(this).load();
});
});

Как потом оказалось, этот баг пофиксили 8 февраля в одной из свежих версий bxSlider, которая доступна на github (с сайта все еще отдается версия 4.1.2 с багом в коробке). Эх, а я было хотел сделать pull request.

Proudly powered by Hexo and Theme by Hacker
© 2018 Denis Zavgorodny