lazy load not work in bootstrap carousel - javascript

I create carousel using bootstrap 3 like this :
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>
and add this code for add img lazy load.
JS :
$('#myCarousel').on('slid', function () {
var $nextImage = $('.active.item', this).next('.item').find('img');
$nextImage.attr('src', $nextImage.data('lazy-load-src'));
});
But, This not work for me!? can do fix this ?
Important Q: can i add image preloader for lazy load?!
DEMO : FIDDLE

The answer by dm4web does not account for skipping slides by directly clicking the carousel indicators. This version correctly loads an image regardless of how you slide to it, using Bootstrap's event.relatedTarget (the item being slid into place, see the official documentation). Try running the snippet below and clicking on the indicators to switch several slides ahead.
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>

http://jsfiddle.net/ys4je40u/
add lazy-load class to item object
use slide.bs.carousel event
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', '');
}
});

If you have multiple images in your slide, you have to use this :
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', '');
}
});
});

Created this "kinda generic" solution some months ago and had no issues so far...
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'));
});
}
All you have to do in HTML is add "carousel-ajax" class to your existing carousel and prepend "data-" in front of your img's src tags:
<img data-src="..." />

Related

Bootstrap carousel is not working in AJAX

I am trying to load bootstrap carousel using AJAX. AJAX return HTML data. HTML is load into my page and all the related JS and CSS is loaded into the page as well. But carousal is not scrolling.
I want to create widget of Jquery which run this carousel any website, after just include the .js on any website
Here is my code index.php
<!doctype html>
<html lang="en">
<head>
<title>Example of the Demo</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm">
One of three columns
</div>
<div class="col-sm">
One of three columns
</div>
<div class="col-sm">
One of three columns
</div>
</div>
<div id="carousel"></div>
</div>
<script src="widget.js"></script>
</body>
</html>
Widget.js
(function () {
// Localize jQuery variable
var jQuery;
/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '3.4.1') {
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src", "https://code.jquery.com/jquery-3.4.1.min.js");
script_tag.setAttribute("crossorigin", "anonymous");
if (script_tag.readyState) {
script_tag.onreadystatechange = function () { // For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
} else { // Other browsers
script_tag.onload = scriptLoadHandler;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
main();
}
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call our main function
main();
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function ($) {
/******* Load CSS *******/
var css_link = $("<link>", {
rel: "stylesheet",
type: "text/css",
href: "http://localhost/demo/php_test_hrn/css/bootstrap.min.css"
});
css_link.appendTo('head');
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src", "http://localhost/demo/php_test_hrn/js/bootstrap.min.js");
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
/******* Load HTML *******/
// We can use jQuery 1.4.2 here
$.get("http://localhost/demo/php_test_hrn/carousel.php", function (data) {
$("#carousel").html(data);
});
});
}
}()); // We call our anonymous function immediately
Carousel.php
<div class="row">
<div id="carouselExampleSlidesOnly" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item active">
<img src="http://localhost/demo/php_test_hrn/images/img1.jpg" class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="http://localhost/demo/php_test_hrn/images/img2.jpg" class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="http://localhost/demo/php_test_hrn/images/img3.jpg" class="d-block w-100" alt="...">
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
after the ajax call, you need to run carousel manually via $('.carousel').carousel()
this should work;
$.get("http://localhost/demo/php_test_hrn/carousel.php", function (data) {
$("#carousel").html(data);
setTimeout(function(){ // just being safe
$('.carousel').carousel();
},20);
});

bootstrap *slide.bs.carousel* event is not firing in vue js

<div id="appFeatureimg" class="carousel slide">
<div class="carousel-inner row w-100 mx-auto">
<div class="carousel-item col-md-3 col-sm-3 col-3" :class= "{active: index==0 }" v-for="(screenshot,index) in app_details.screenshots">
<div class="panel panel-default">
<div class="panel-thumbnail">
<a href="#" class="thumb">
<img class="img-fluid mx-auto d-block" :src="screenshot"alt="slide 1" >
</a>
</div>
</div>
</div>
</div>
<a class="carousel-control-prev" href="#appFeatureimg" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next text-faded" href="#appFeatureimg" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
This is my html where i generate carousel item
<script>
vue js code goes here
</script>
and other js code
<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.13.0/umd/popper.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script>
$( document ).ready(() => {
console.log('ready');
$('#appFeatureimg').on('slide.bs.carousel', (e) => {
console.log('ready2');
var $e = $(e.relatedTarget);
var idx = $e.index();
var itemsPerSlide = 4;
var totalItems = $('.carousel-item').length;
if (idx >= totalItems-(itemsPerSlide-1)) {
var it = itemsPerSlide - (totalItems - idx);
for (var i=0; i<it; i++) {
// append slides to end
if (e.direction=="left") {
$('.carousel-item').eq(i).appendTo('.carousel-inner');
}
else {
$('.carousel-item').eq(0).appendTo('.carousel-inner');
}
}
}
});
});
</script>
and this is my jQuery for carousel.
After document.ready function I get my console print but bootstrap event slide.bs.carousel is not firing.
i put those code before my vue js and other script but no result.
any suggestion will be really appreciable.
Move this
$( document ).ready(() => {
console.log('ready');
$('#appFeatureimg').on('slide.bs.carousel', (e) => {
console.log('ready2');
var $e = $(e.relatedTarget);
var idx = $e.index();
var itemsPerSlide = 4;
var totalItems = $('.carousel-item').length;
if (idx >= totalItems-(itemsPerSlide-1)) {
var it = itemsPerSlide - (totalItems - idx);
for (var i=0; i<it; i++) {
// append slides to end
if (e.direction=="left") {
$('.carousel-item').eq(i).appendTo('.carousel-inner');
}
else {
$('.carousel-item').eq(0).appendTo('.carousel-inner');
}
}
}
});
to the mounted section of vue js component

Carousel thumb slider stop clone when item less than 3

I am using bootstrap carousel slider now my slider repeating all times . I need to stop repeating item when item count less than 3. I have tried below script. Anyone help me to achieve this.
<div id="carousel" class="carousel slide" data-ride="carousel" data-interval="false">
<div class="carousel-inner">
<div class="item active">
<img src="images/homogeneous/marvel-stone/marvel-stone-detail.jpg" alt="">
</div>
</div>
</div>
<div class="clearfix">
<div id="myCarousel" class="carousel slide" data-interval="false">
<div class="carousel-inner">
<div class="item active">
<div class="thumb"><img src="images/homogeneous/marvel-stone/marvel-stone-thumb1.png" alt=""></div>
</div>
<div class="item">
<div class="thumb"><img src="images/homogeneous/marvel-stone/marvel-stone-thumb2.png" alt=""></div>
</div>
<div class="item">
<div class="thumb"><img src="images/homogeneous/marvel-stone/marvel-stone-thumb3.png" alt=""></div>
</div>
<div class="item">
<div class="thumb"><img src="images/homogeneous/marvel-stone/marvel-stone-thumb4.png" alt=""></div>
</div>
</div>
<!-- /carousel-inner -->
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</div>
<!-- /myCarousel -->
</div>
<!-- /clearfix -->
Script I was tried for 3 items. But I don't know how to write up for 2 and 1 items with simplified script.
$('#myCarousel').carousel({
interval: false
});
var totalItems = $('.item').length;
if (totalItems > 3) {
//alert();
$('.carousel .item').each(function() {
var next = $(this).next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
if (next.next().length > 0) {
next.next().children(':first-child').clone().appendTo($(this)).addClass('rightest');
} else {
$(this).siblings(':first').children(':first-child').clone().appendTo($(this));
}
});
} else {
//what to be here
}
my code here
This one working for me.
$('#myCarousel').carousel({
interval: false
});
var totalItems = $('.item').length;
if (totalItems > 3) {
//alert();
$('.carousel .item').each(function(){
var next = $(this).next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
if (next.next().length>0) {
next.next().children(':first-child').clone().appendTo($(this)).addClass('rightest');
}
else {
$(this).siblings(':first').children(':first-child').clone().appendTo($(this));
}
});
}
else {
//alert("hello");
(function(){
$('.carousel .item').each(function(){
var itemToClone = $(this);
for (var i=1;i<2;i++) {
itemToClone = itemToClone.next();
// wrap around if at end of item collection
if (!itemToClone.length) {
itemToClone = $(this).siblings(':first');
}
// grab item, clone, add marker class, add to collection
itemToClone.children(':first-child').clone()
.addClass("cloneditem-"+(i))
.appendTo($(this));
//listener for after slide
jQuery('.carousel').on('slid.bs.carousel', function(){
//Each slide has a .item class to it, you can get the total number of slides like this
var totalItems = jQuery('.carousel .item').length;
//find current slide number
var currentIndex = jQuery('.carousel .item div.active').index() + 1;
//if slide number is last then stop carousel
if(totalItems == currentIndex){
clearInterval(jQuery('.carousel .item').data('bs.carousel').interval);
} // end of if
});
}
});
}());
}

Bootstrap Carousel with different hashtag URL ID

I have created a separate URL for each slide of the Bootstrap Carousel. However, it currently uses numbers with a hashtag in the following way:
domain.net/pride#1
domain.net/pride#2
domain.net/pride#3
Is there a way I can have it change to what I want? Something like:
domain.net/pride#events
domain.net/pride#press
domain.net/pride#schedule
Thank You.
<script>
var url = document.location.toString();
if (url.match('#')) {
// Clear active item
jQuery('.carousel-inner div').removeClass('active');
// Activate item number #hash
var index = url.split('#')[1];
jQuery('.carousel-inner div:nth-child(' + index + ')').addClass('active');
}
jQuery('#PrideCr').bind('slid', function (e) {
// Update location based on slide (index is 0-based)
var item = jQuery('#PrideCr .carousel-inner .item.active');
window.location.hash = "#"+parseInt(item.index()+1);
})
</script>
2) by the data-name attribute
http://glebkema.ru/tasks/so-38407398.html
var url = document.location.toString();
if (url.match('#')) {
// Clear active item
$('#PrideCr .item.active').removeClass('active');
// Activate item number #hash
var index = url.split('#')[1];
$('#PrideCr .item[data-name="' + index + '"]').addClass('active');
}
$('#PrideCr').on('slid.bs.carousel', function () {
// Update location based on slide
var item = $(this).find('.item.active').data('name');
if (item) window.location.hash = "#" + item; // Doesn't work on SO
console.log(item);
})
.carousel-inner img {
height: auto;
width: 100%;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div id="PrideCr" class="carousel slide" data-ride="carousel">
<div class="carousel-inner" role="listbox">
<div data-name="events" class="item active">
<img src="http://placehold.it/600x150/c69/f9c/?text=events" alt="">
</div>
<div data-name="press" class="item">
<img src="http://placehold.it/600x150/9c6/cf9/?text=press" alt="">
</div>
<div data-name="schedule" class="item">
<img src="http://placehold.it/600x150/69c/9cf/?text=schedule" alt="">
</div>
</div>
<a class="left carousel-control" href="#PrideCr" 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="#PrideCr" role="button" data-slide="next"><span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span><span class="sr-only">Next</span></a>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
1) by the id attribute
I guess you can add the id attribute to carousel's items and use this attribute in your script. Something like this:
<div class="carousel-inner" role="listbox">
<div id="events" class="item active">
<img src="..." alt="...">
</div>
<div id="press" class="item">
<img src="..." alt="...">
</div>
<div id="schedule" class="item">
<img src="..." alt="...">
</div>
</div>
<script>
var url = document.location.toString();
if (url.match('#')) {
// Clear active item
jQuery('#PrideCr .item.active').removeClass('active');
// Activate item number #hash
var index = url.split('#')[1];
jQuery('#' + index).addClass('active');
}
jQuery('#PrideCr').bind('slid', function (e) {
// Update location based on slide
var item = jQuery('#PrideCr .item.active').attr('id');
if (item) window.location.hash = "#" + item;
})
</script>

show next item title on previous next hover carousel

I am using twitter bootstarp carousel in my web page. I need to show the title of next item on mouse over over the next arrow.
Html:
<div id="carousel-example-generic" class="carousel slide homecarousel" data-ride="carousel">
<!-- FIRST for slide -->
<div class="carousel-inner">
<div class="item active" title="Adult">
slider 1
</div>
<div class="item" title="Baby">
slider 2
</div>
<div class="item" title="Ingredients">
slider 3
</div>
<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev" ><img src="images/arrow_left.png" alt=""></a>
<a class="right carousel-control" href="#carousel-example-generic" data-slide="next" ><img src="images/arrow_right.png" alt=""></a>
</div>
</div>
How to achieve this? Any help would be appreciated. Thanks.
Something like this? :
$('.carousel-control').on('mouseover', function() {
var titles = $('.carousel-inner .item').map(function(){ return this.title; });
var currentIndex = $('.carousel .active').prevAll('.item').length;
var title = titles[currentIndex + 1 > titles.length -1 ? 0 : currentIndex + 1];
if ($(this).hasClass('left')) {
title = titles[currentIndex - 1 < 0 ? titles.length - 1 : currentIndex - 1];
}
$(this).attr('title', title);
});
Fiddle

Categories