I have a slick carousel where I'm trying to create separate captions from the img alt tags. However its not working and I'm not getting any errors.
I'd like to get the caption from the img alt tag of each and then wrap them in a separate div, which then changes as you go through the images within the carousel
Markup below:
jQuery(document).ready(() => {
var helpers = {
addZeros: function (n) {
return (n < 10) ? '0' + n : '' + n;
}
};
$('.carousel-module').each(function (index, sliderWrap) {
var $sliderParent = $(this).parent();
var $slider = $(sliderWrap).find('.carousel-gallery');
var $caption = $('.carousel-caption');
$slider.slick({
dots: false,
arrows: false,
speed: 900,
autoplay: true,
autoplaySpeed: 4000,
fade: true,
cssEase: 'linear'
});
if ($(this).find('.item').length > 1) {
$(this).siblings('.carousel-numbers').show();
}
$(this).on('afterChange', function(event, slick, currentSlide){
$sliderParent.find('.carousel-numbers .active').html(helpers.addZeros(currentSlide + 1));
var slideCaption = $('.carousel-gallery .slick-slide img').attr('alt');
$(this).parent().parent().parent().append('<div class="slidecaption">' + slideCaption + '</div>');
});
var sliderItemsNum = $(this).find('.slick-slide').not('.slick-cloned').length;
$sliderParent.find('.carousel-numbers .total').html(helpers.addZeros(sliderItemsNum));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
<section class="carousel-module">
<div class="container">
<div class="carousel-numbers" style="display: block;">
<span class="active">01</span> / <span class="total"></span>
</div>
<div class="carousel-caption">
</div>
<div class="carousel-gallery">
<div class="carousel__item">
<img src="https://images.unsplash.com/photo-1661462328450-e0fa1bac6423?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1528&q=80" alt="test1" title="testing" />
</div>
<div class="carousel__item">
<img src="https://images.unsplash.com/photo-1661459479190-fd1cdad5ffd4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80" alt="test2" title="testing"/>
</div>
<div class="carousel__item">
<img src="http://via.placeholder.com/750x350)" alt="test3" title="testing"/>
</div>
<div class="carousel__item">
<img src="http://via.placeholder.com/750x350)" alt="test4" title="testing"/>
</div>
<div class="carousel__item">
<img src="http://via.placeholder.com/750x350)" alt="test5" title="testing"/>
</div>
</div>
</div>
</section>
Here is clean code:
jQuery(document).ready(() => {
const addZeroPad = (val) => val.toString().padStart(2, "0");
$(".carousel-module").each(function() {
const $module = $(this);
const $slider = $module.find(".carousel-gallery");
const $caption = $module.find(".carousel-caption");
const $slides = $slider.find(".carousel__item");
const $numbersElem = $module.find(".carousel-numbers");
const $totalNumElem = $module.find(".carousel-numbers .total");
const $activeNumElem = $module.find(".carousel-numbers .active");
const changeCaption = (value) =>
$caption.html('<h4 class="slidecaption">' + value + "</div>");
if ($slides.length) {
$slider.on("init", function(event, slick) {
console.log(slick.$slides.length);
$totalNumElem.text(addZeroPad(slick.$slides.length));
$numbersElem.show();
const slideCaption = $(slick.$slides.get(0)).find("img").attr("alt");
changeCaption(slideCaption);
});
$slider.on("afterChange", function(event, slick, currentSlide) {
$activeNumElem.text(addZeroPad(currentSlide + 1));
const slideCaption = $(slick.$slides.get(currentSlide))
.find("img")
.attr("alt");
changeCaption(slideCaption);
});
$slider.slick({
dots: true,
arrows: true,
autoplay: true,
});
}
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Jost:wght#400;600;700&display=swap" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/css/bootstrap-grid.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
<script src="demo.js"></script>
<style>
body {
font-family: 'Jost', sans-serif;
}
.carousel-module img {
width: 100%;
}
</style>
</head>
<body>
<section class="carousel-module">
<div class="container">
<div class="carousel-numbers" style="display: block">
<h1><span class="active">01</span> / <span class="total"></span></h1>
</div>
<div class="carousel-caption"></div>
<div class="carousel-gallery">
<div class="carousel__item">
<img src="https://picsum.photos/id/1013/750/300" alt="test1" title="testing" />
</div>
<div class="carousel__item">
<img src="https://picsum.photos/id/1023/750/300" alt="test2" title="testing" />
</div>
<div class="carousel__item">
<img src="https://picsum.photos/id/1022/750/300" alt="test3" title="testing" />
</div>
<div class="carousel__item">
<img src="https://picsum.photos/id/1056/750/300" alt="test4" title="testing" />
</div>
<div class="carousel__item">
<img src="https://picsum.photos/id/1026/750/300" alt="test5" title="testing" />
</div>
</div>
</div>
</section>
</body>
</html>
For start, I made your carousel work here in a snippet. I can get the current slide using the .slick-active class (although there are other ways). Then I get the attribute alt and update the .caption element.
jQuery(document).ready(() => {
var helpers = {
addZeros: function(n) {
return (n < 10) ? '0' + n : '' + n;
}
};
$('.carousel-module').each(function(index, sliderWrap) {
var $sliderParent = $(this).parent();
var $slider = $(sliderWrap).find('.carousel-gallery');
var $caption = $('.carousel-caption');
$slider.slick({
speed: 900,
autoplay: true,
autoplaySpeed: 4000,
fade: false,
cssEase: 'linear'
});
if ($(this).find('.item').length > 1) {
$(this).siblings('.carousel-numbers').show();
}
$(this).on('afterChange', function(event, slick, currentSlide) {
$sliderParent.find('.carousel-numbers .active').html(helpers.addZeros(currentSlide + 1));
var slideCaption = $('.carousel-gallery .slick-slide.slick-active img').attr('alt');
$(this).closest(".carousel-module").find('.carousel-caption').text(slideCaption);
});
var sliderItemsNum = $(this).find('.slick-slide').not('.slick-cloned').length;
$sliderParent.find('.carousel-numbers .total').html(helpers.addZeros(sliderItemsNum));
});
});
.carousel-module {
width: 200px;
margin: 20px;
}
img {
width: 100%
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.css" integrity="sha512-wR4oNhLBHf7smjy0K4oqzdWumd+r5/+6QO/vDda76MW5iug4PT7v86FoEkySIJft3XA0Ae6axhIvHrqwm793Nw==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
<section class="carousel-module">
<div class="container">
<div class="carousel-numbers" style="display: block;">
<span class="active">01</span> / <span class="total"></span>
</div>
<div class="carousel-caption">
Hello world
</div>
<div class="carousel-gallery">
<div class="carousel__item">
<img src="https://picsum.photos/180" alt="test1" title="testing" />
</div>
<div class="carousel__item">
<img src="https://picsum.photos/180" alt="test2" title="testing" />
</div>
<div class="carousel__item">
<img src="https://picsum.photos/180" alt="test3" title="testing" />
</div>
<div class="carousel__item">
<img src="https://picsum.photos/180" alt="test4" title="testing" />
</div>
<div class="carousel__item">
<img src="https://picsum.photos/180" alt="test5" title="testing" />
</div>
</div>
</div>
</section>
I have a Slick Slider with text on top of the images on each slide. The text should fade in when the current slide has the class .slick-active. Then when the slide doesn't have the class .slick-active anymore the text should become invisible and the text on the next slide should fade in and so on every time the slider changes the current slide. When the page loads for the first time everything seems to be working fine and as expected. The problem is that on page reload, or if one visits another page and then returns to the slider page, the text on the first slide fades in as expected but not on the other slides. It seems like the .on('afterChange') event fires because when using Chrome Dev Tools one can see that jQuery changes the opacity from 0 to 1 via .fadeTo(1), however, the text is not visible. But if one reloads enough times then the text fades in as expected. Also if one resizes the browser window the text becomes visible at certain browser size but at other browser sizes the text disappears. To me it seems like something is off with jQuery itself but I'm not sure.
Edit: this weird behaviour only happens if using Google Chrome or Opera (in Opera the text only shows up on the first slide even if it is the first time the page is loaded), seems to be working fine and as expected in both Safari and Mozilla Firefox. So some sort of Google Chrome / Opera + jQuery bug?
If someone could help it would be much appreciated!
HTML:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Lazzo</title>
<link rel="stylesheet" type="text/css" href="css/normalize.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<link rel="stylesheet" type="text/css" href="css/bars.css">
<link rel="stylesheet" type="text/css" href="slick/slick.css"/>
<link rel="stylesheet" type="text/css" href="slick/slick-theme.css"/>
<link rel="stylesheet" type="text/css" href="css/custom-slick.css">
<link rel="stylesheet" type="text/css" href="css/animate.css">
<link rel="stylesheet" href="https://use.typekit.net/jqi8pst.css">
</head>
<body>
<div class="container">
<header>
<div class="white logotype">
<a href="index.html">
<svg class="logotype-is-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 312.68 110.26"><path d="M19.91,91.14a2.38,2.38,0,1,0,0-4.75c-14.1,0-14.1-7.75-14.1-14v-70a2.38,2.38,0,1,0-4.76,0v70C1.05,78.49,1.05,91.14,19.91,91.14Z"/><path d="M55,51.78c-7.29,0-13.25,1.16-17.71,3.45C30.71,58.63,26.91,64.88,27.15,72c.24,7.3,4.85,13.75,12,16.85A41,41,0,0,0,55.6,91.94c6.92,0,15.92-.91,22-4.92a9.13,9.13,0,0,0,8.06,4.14,2.38,2.38,0,1,0,0-4.76c-3.3,0-5-1.92-5-5.71V46.26c0-7.1-4.37-12.77-12.29-16-13.7-5.54-30.34-1.57-37.28,5.62a2.38,2.38,0,0,0,.05,3.36,2.42,2.42,0,0,0,1.7.67,2.36,2.36,0,0,0,1.67-.73C41,32.51,56,30.4,66.61,34.69c3.48,1.41,9.32,4.78,9.32,11.57v5.52Zm21,30.5c-5.2,4.24-14.92,4.91-20.43,4.91a36.31,36.31,0,0,1-14.53-2.75c-5.47-2.36-9-7.21-9.17-12.65a13.25,13.25,0,0,1,7.59-12.33c3.78-1.94,9-2.93,15.54-2.93h20.9V80.69A13.57,13.57,0,0,0,76,82.28Z"/><path d="M97.45,33.69h39.09l-41,53.63a2.37,2.37,0,0,0,1.88,3.82h43.89a2.38,2.38,0,1,0,0-4.75H102.26l41-53.64a2.37,2.37,0,0,0-1.89-3.81H97.45a2.38,2.38,0,0,0,0,4.75Z"/><path d="M157.6,33.69h39.08l-41,53.64a2.37,2.37,0,0,0,1.9,3.81h43.88a2.38,2.38,0,1,0,0-4.75H162.4l41-53.64a2.37,2.37,0,0,0-1.9-3.81H157.6a2.38,2.38,0,1,0,0,4.75Z"/><path d="M262.85,10.6a49.83,49.83,0,0,0-21.28,94.9H2.38a2.38,2.38,0,1,0,0,4.75H262.85a49.83,49.83,0,0,0,0-99.66Zm.06,94.9h-.4a45.21,45.21,0,1,1,.4,0Z"/></svg>
</a>
</div><!-- /logotype -->
<div class="bars bars--slider">
<div class="bars-box">
<div class="white bars-inner">
</div><!-- /bars-inner -->
</div><!-- /bars-box -->
</div><!-- /bars bars--slider -->
</header>
<nav class="menu">
<ul>
<li>
CASE
</li>
<li>
OM
</li>
<li>
KONTAKT
</li>
</ul>
<footer>
<div class="contact">
0500 – 49 43 43
<div class="contact-divider">
|
</div><!-- /contact-divider -->
info#lazzo.nu
</div><!-- /contact -->
</footer>
</nav>
<div class="fullscreen content-slider big">
<div>
<div class="overlay">
<div class="heading-one">
<h3>Jönköpings Länstrafik</h3>
<h1>Världsnyheten i Värnamo</h1>
<a class="white" href="case.html">Se case</a>
</div><!-- /heading-one -->
</div><!-- /overlay -->
<img src="img/vasttrafik.jpg" alt="Västtrafik">
</div>
<div>
<div class="overlay">
<div class="heading-one">
<h3>Hotell Kungshamn</h3>
<h1>Omprofilering</h1>
<a class="white" href="case.html">Se case</a>
</div><!-- /heading-one -->
</div><!-- /overlay -->
<img src="img/hotellkungshamn.jpg" alt="Hotell Kungshamn">
</div>
<div>
<div class="overlay">
<div class="heading-one">
<h3>AH Automation</h3>
<h1>Robotmässa</h1>
<a class="white" href="case.html">Se case</a>
</div><!-- /heading-one -->
</div><!-- /overlay -->
<video autoplay loop muted>
<source src="video/ahautomation.mp4" type="video/mp4">
</video>
</div>
</div><!-- /fullscreen content-slider -->
</div><!-- /container -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="js/custom-slick.js"></script>
<script src="js/white-bars.js"></script>
<script src="slick/slick.js"></script>
</body>
</html>
jQuery:
$(document).ready(function(){
$('.big').on('init', function(event, slick){
$('.slick-active .heading-one').delay(500).fadeTo(300, 1);
});
$('.big').on('reInit', function(event, slick){
$('.slick-active .heading-one').delay(500).fadeTo(300, 1);
});
$('.big').on('beforeChange', function(event, slick, currentSlide, nextSlide){
$('.slick-active .heading-one').css('opacity', '0');
});
$('.big').on('afterChange', function(event, slick, currentSlide){
$('.slick-active .heading-one').fadeTo(300, 1);
});
//slick
$('.big').slick({
autoplay: false,
prevArrow: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.1 25.71" class="slick-prev"><polygon points="12.4,25.5 13.8,24.1 3,12.9 13.8,1.6 12.4,0.2 0.3,12.9 "/></svg>',
nextArrow: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.1 25.71" class="slick-next"><polygon points="1.7,25.5 0.3,24.1 11.1,12.9 0.3,1.6 1.7,0.2 13.8,12.9 "/></svg>',
fade: true,
pauseOnFocus: false,
pauseOnHover: false,
speed: 700,
});
$('.small').slick({
prevArrow: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.1 25.71" class="slick-prev"><polygon points="12.4,25.5 13.8,24.1 3,12.9 13.8,1.6 12.4,0.2 0.3,12.9 "/></svg>',
nextArrow: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.1 25.71" class="slick-next"><polygon points="1.7,25.5 0.3,24.1 11.1,12.9 0.3,1.6 1.7,0.2 13.8,12.9 "/></svg>',
pauseOnFocus: false,
pauseOnHover: false,
slidesToShow: 3,
slidesToScroll: 1,
speed: 700,
responsive: [
{
breakpoint: 1114,
settings: {
slidesToShow: 2,
}
},
{
breakpoint: 784,
settings: {
slidesToShow: 1,
}
},
],
});
});
I think you're probably overcomplicating it a bit; the desired behaviour can be achieved without additional JavaScript:
.heading-one {
opacity: 0;
transition: opacity .3s;
}
.slick-active .heading-one {
opacity: 1;
}