I've tried (and failed) to write some javascript that gets the data-attribute from the 'active' slide of a carousel, then adds the same text into a p tag outside the container. When the carousel gets a new 'active' slide, the text should change - fading slightly if possible.
I don't want the caption to appear within the carousel and overflow: hidden prevents me from adding a caption within the slide and then positioning it outside with absolute.
If easier, I could get the text from a p within the slide rather data-. Then just hide the text within.
This was my attempt:
var caption = document.querySelector(".caption");
if(document.querySelector(".swiper-slide").classList.contains("swiper-slide-active")){
console.log(this.getAttribute('data-caption'));
caption.innerHTML('data-caption');
}
I found a CodePen using the same carousel so I thought I'd add a basic example to check what happens when the class is added/removed from the active slides.
CodePen: https://codepen.io/moy/pen/OJOyGKR
Thanks in advance, hope someone can tell me where I'm going wrong. Keen to understand JS a bit more!
CodePudding user response:
Swiper JS, Events Docs has useful Event methods like init, slideChange etc, which are part of the options on Object.
Such event callback functions are made in order trigger a desired function once the Swiper performs an internal change. It's a way to say: "When you do this, let me also do that"
Here's how your JS should look:
const EL_caption = document.querySelector(".caption");
function doSomethingWithActiveSlide() {
const EL_currentSlide = this.slides[this.activeIndex - 1];
EL_caption.innerHTML = EL_currentSlide.dataset.caption;
}
const MySwiper = new Swiper('.swiper-container', {
loop: true,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
pagination: {
el: '.swiper-pagination',
},
// Events
on: {
init: doSomethingWithActiveSlide,
slideChange: doSomethingWithActiveSlide,
}
});
CodePudding user response:
You can use activeIndexChange event for this, found back at:
https://swiperjs.com/swiper-api#event-activeIndexChange
var caption = document.querySelector(".caption");
var Swipes = new Swiper('.swiper-container', {
loop: true,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
pagination: {
el: '.swiper-pagination',
},
on: {
init: function() {
updateCaptionText(this);
},
activeIndexChange: function() {
updateCaptionText(this);
}
}
});
function updateCaptionText(slider) {
caption.textContent = slider.slides[slider.activeIndex].dataset.caption
}
// external css https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.3.3/css/swiper.css
// tat for styling is from line 50 >
.swiper-container {
width: 100%;
}
.swiper-slide {
background-size: cover;
background-position: 50%;
min-height: 20vh;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.caption {
background: red;
position: fixed;
top: 0;
left: 0;
text-align: center;
width: 100%;
z-index: 10000;
}
// overwrite swiper defaults
.swiper-pagination {
&-bullet {
background-color: transparent;
border: 2px solid #fff;
border-radius: 50%;
width: 12px;
height: 12px;
opacity: 1;
}
&-bullet-active {
background-color: #fff;
}
}
.swiper-button {
&-container {
background-color: rgba(0, 0, 0, 0.25);
}
&-prev {
background-image: url("data:image/svg xml;charset=utf-8,");
}
&-next {
background-image: url("data:image/svg xml;charset=utf-8,");
}
}
// GENERIC STUFF TO MAKE IT POP 