Ленивая нагрузка не работает в карусели бутстрапа

Я создаю карусель с помощью бутстрапа 3 следующим образом:

HTML:

<div id="myCarousel" class="carousel slide">
    <div class="carousel-inner">
        <div class="active item">
            <img src="http://rivathemes.net/html/envor/img/posts/3.jpg" class="img-big">
        </div>
        <div class="item">
            <img data-lazy-load-src="http://rivathemes.net/html/envor/img/posts/4.jpg" class="img-big">
        </div>
    </div>
    <div class="carousel-controls">
<a class="left carousel-control" href="#myCarousel" data-slide="prev"><i class="fa fa-angle-double-left fa-lg"></i></a>

<a class="right carousel-control" href="#myCarousel" data-slide="next"><i class="fa fa-angle-double-right fa-lg"></i></a>

    </div>
</div>

и добавьте этот код для добавления img ленивой загрузки.

JS:

$('#myCarousel').on('slid', function () {
    var $nextImage = $('.active.item', this).next('.item').find('img');
    $nextImage.attr('src', $nextImage.data('lazy-load-src'));
});

Но это не работает для меня!? может это исправить?

Важный вопрос: могу ли я добавить предварительный загрузчик изображений для ленивой загрузки?!

DEMO: FIDDLE

Ответы

Ответ 1

http://jsfiddle.net/ys4je40u/

  • добавить lazy-load класс в объект объекта
  • использовать slide.bs.carousel событие

CSS

.lazy-load {
    background: url("http://www.mozart.it/images/preloader.gif") center center no-repeat;
}

JQ:

var cHeight = 0;

$('#myCarousel').on('slide.bs.carousel', function (e) {
    var $nextImage = null;

    $activeItem = $('.active.item', this);

    if (e.direction == 'left'){
        $nextImage = $activeItem.next('.item').find('img');
    } else {
        if ($activeItem.index() == 0){
            $nextImage = $('img:last', $activeItem.parent());
        } else {
            $nextImage = $activeItem.prev('.item').find('img');
        }
    }

    // prevents the slide decrease in height
    if (cHeight == 0) {
       cHeight = $(this).height();
       $activeItem.next('.item').height(cHeight);
    }

    // prevents the loaded image if it is already loaded
    var src = $nextImage.data('lazy-load-src');

    if (typeof src !== "undefined" && src != "") {
       $nextImage.attr('src', src)
       $nextImage.data('lazy-load-src', '');
    }
});

Ответ 2

Ответ dm4web не учитывает пропуски слайдов, просто нажав на индикаторы карусели. Эта версия правильно загружает изображение независимо от того, как вы на него нажимаете, используя Bootstrap event.relatedTarget (элемент соскальзывает на место, см. официальную документацию). Попробуйте запустить снимок ниже и щелкнуть по индикаторам, чтобы переключить несколько слайдов вперед.

var cHeight = 0;

$('#carousel-example-generic').on('slide.bs.carousel', function(e) {

  var $nextImage = $(e.relatedTarget).find('img');

  $activeItem = $('.active.item', this);

  // prevents the slide decrease in height
  if (cHeight == 0) {
    cHeight = $(this).height();
    $activeItem.next('.item').height(cHeight);
  }

  // prevents the loaded image if it is already loaded
  var src = $nextImage.data('lazy-load-src');

  if (typeof src !== "undefined" && src != "") {
    $nextImage.attr('src', src)
    $nextImage.data('lazy-load-src', '');
  }
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

<div class="container-fluid">

  <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
    <!-- Indicators -->
    <ol class="carousel-indicators">
      <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
      <li data-target="#carousel-example-generic" data-slide-to="1"></li>
      <li data-target="#carousel-example-generic" data-slide-to="2"></li>
      <li data-target="#carousel-example-generic" data-slide-to="3"></li>
      <li data-target="#carousel-example-generic" data-slide-to="4"></li>
    </ol>

    <!-- Wrapper for slides -->
    <div class="carousel-inner" role="listbox">
      <div class="item active">
        <img src="http://placehold.it/5000x1000">
      </div>
      <div class="item">
        <img data-lazy-load-src="http://placehold.it/5001x1000">
      </div>
      <div class="item">
        <img data-lazy-load-src="http://placehold.it/5002x1000">
      </div>
      <div class="item">
        <img data-lazy-load-src="http://placehold.it/5003x1000">
      </div>
      <div class="item">
        <img data-lazy-load-src="http://placehold.it/5004x1000">
      </div>
    </div>

    <!-- Controls -->
    <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
      <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
      <span class="sr-only">Previous</span>
    </a>
    <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
      <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
      <span class="sr-only">Next</span>
    </a>
  </div>

</div>

Ответ 3

Создал это "своеобразное общее" решение несколько месяцев назад и не имел проблем до сих пор...

var $ajaxCarousel = $('.carousel-ajax');

if ($ajaxCarousel.length > 0) {
    $ajaxCarousel.on('slide.bs.carousel', function (e) {
        var $upcomingImage = $(e.relatedTarget).find('img');
        if (typeof $upcomingImage.attr('src') === 'undefined') {
            $upcomingImage.attr('src', $upcomingImage.data('src'));
        }
    });
    // preload first image
    $ajaxCarousel.each(function() {
        var $firstImage = $(this).find('[data-slide-number=0]').find('img');

        $firstImage.attr('src', $firstImage.data('src'));
    });
}

Все, что вам нужно сделать в HTML, - добавить класс "carousel-ajax" к существующей карусели и добавить "данные" перед вашими тегами img src:

<img data-src="..." />

Ответ 4

Если на слайде есть несколько изображений, вы должны использовать это:

var cHeight = 0;

$('#carousel').on('slide.bs.carousel', function (e) {
    var $nextImage = null;

    $activeItem = $('.active.item', this);

    if (e.direction == 'left'){
        $nextImage = $activeItem.next('.item').find('img');
    } else {
        if ($activeItem.index() == 0){
            $nextImage = $('img:last', $activeItem.parent());
        } else {
            $nextImage = $activeItem.prev('.item').find('img');
        }
    }

    // prevents the slide decrease in height
    if (cHeight == 0) {
       cHeight = $(this).height();
       $activeItem.next('.item').height(cHeight);
    }

    // => Changes here ! 
    // prevents the loaded images if it is already loaded
    $nextImage.each(function(){
        var $this = $(this),
            src = $this.data('original');

        if (typeof src !== "undefined" && src != "") {
           $this.attr('src', src)
           $this.data('original', '');
        }
    });
});