I am currently building a carousel with vanilla JS and I've noticed that, unlike previous carousels I built before with jQuery, this one slides an extra slide out of the loop (which I defined with the .length property). The problem is happening in both directions.
Why is this happening and what can I do to fix it? Here's a quick example:
let currentSlide = 0
const holder = document.querySelector('.holder')
const totalSlides = holder.querySelectorAll('.holder-child')
const next = document.querySelector('.next')
const prev = document.querySelector('.prev')
const moveSlide = slide => {
const leftPosition = -slide * 100 + 'vw'
holder.style.left = leftPosition
}
const nextSlide = () => {
currentSlide = currentSlide + 1
moveSlide(currentSlide)
if (currentSlide > totalSlides.length - 1) {
currentSlide = 0
}
}
const prevSlide = () => {
currentSlide = currentSlide - 1
moveSlide(currentSlide)
if (currentSlide < 0) {
currentSlide = totalSlides.length - 1
}
}
next.addEventListener('click', () => {
nextSlide()
})
prev.addEventListener('click', () => {
prevSlide()
})
.flex {
display: flex;
}
.slideshow {
position: relative;
overflow: hidden;
width: 100vw;
}
.holder {
position: relative;
top: 0;
left: 0;
width: 500vw;
transition: left 1s;
}
.holder-child {
display: flex;
width: 100vw;
}
.speaker {
padding: 0 8vw 0 8vw;
}
.controls {
justify-content: space-between;
}
<h2>Test</h2>
<div class="slideshow">
<div class="controls flex">
<p class="prev pointer">prev</p>
<p class="next pointer">next</p>
</div>
<div class=" holder flex">
<div class="holder-child">
<p>slide 1</p>
</div>
<div class="holder-child">
<p>slide 2</p>
</div>
</div>
JSFiddle: https://jsfiddle.net/5f8cbxdr/
It looks like a minor logic issue caused by moveSlide() being called prior to the final calculation of currentSlide during your prevSlide() and nextSlide() methods.
Consider moving the call of moveSlide() to the end of your prevSlide() and nextSlide() functions. This will mean that when the edge cases occur (ie your currentSlide is at either end of the range of slides), the subsequent call to moveSlide() will cause the slides to be positioned base on the re-adjusted value of currentSlide:
let currentSlide = 0
const holder = document.querySelector('.holder')
const totalSlides = holder.querySelectorAll('.holder-child')
const next = document.querySelector('.next')
const prev = document.querySelector('.prev')
const moveSlide = slide => {
const leftPosition = -slide * 100 + 'vw'
holder.style.left = leftPosition
}
const nextSlide = () => {
currentSlide = currentSlide + 1
if (currentSlide > totalSlides.length - 1) {
currentSlide = 0
}
/* Final value for currentSlide now determined, so call moveSlide()
to position slides consistently with most up to date currentSlide
value */
moveSlide(currentSlide)
}
const prevSlide = () => {
currentSlide = currentSlide - 1
if (currentSlide < 0) {
currentSlide = totalSlides.length - 1
}
/* Final value for currentSlide now determined, so call moveSlide()
to position slides consistently with most up to date currentSlide
value */
moveSlide(currentSlide)
}
next.addEventListener('click', () => {
nextSlide()
})
prev.addEventListener('click', () => {
prevSlide()
})
.flex {
display: flex;
}
.slideshow {
position: relative;
overflow: hidden;
width: 100vw;
}
.holder {
position: relative;
top: 0;
left: 0;
width: 500vw;
transition: left 1s;
}
.holder-child {
display: flex;
width: 100vw;
}
.speaker {
padding: 0 8vw 0 8vw;
}
.controls {
justify-content: space-between;
}
<h2>Test</h2>
<div class="slideshow">
<div class="controls flex">
<p class="prev pointer">prev</p>
<p class="next pointer">next</p>
</div>
<div class=" holder flex">
<div class="holder-child">
<p>slide 1</p>
</div>
<div class="holder-child">
<p>slide 2</p>
</div>
</div>
Related
I recently was playing around with the code showcase in this tutorial: Touch Slider CodePen
I would like to use something like this but with videos instead of images.
I swapped the HTML, JS, and CSS code to work with the tag. With this, the code does work and you are able to scroll over one video initially just like the images had worked. After this, it seems the js 'isDragging' or some event in te JS seems to freeze and I am unable to slide to another video or image.
Would anyone be able to play around with the JS shown in this CodePen and get a working slider with videos?
Thanks!
slides = Array.from(document.querySelectorAll('.slide'))
let isDragging = false,
startPos = 0,
currentTranslate = 0,
prevTranslate = 0,
animationID = 0,
currentIndex = 0
slides.forEach((slide, index) => {
const slideImage = slide.querySelector('video')
slideImage.addEventListener('dragstart', (e) => e.preventDefault())
// Touch events
slide.addEventListener('touchstart', touchStart(index))
slide.addEventListener('touchend', touchEnd)
slide.addEventListener('touchmove', touchMove)
// Mouse events
slide.addEventListener('mousedown', touchStart(index))
slide.addEventListener('mouseup', touchEnd)
slide.addEventListener('mouseleave', touchEnd)
slide.addEventListener('mousemove', touchMove)
})
// Disable context menu
window.oncontextmenu = function (event) {
event.preventDefault()
event.stopPropagation()
return false
}
function touchStart(index) {
return function (event) {
currentIndex = index
startPos = getPositionX(event)
isDragging = true
// https://css-tricks.com/using-requestanimationframe/
animationID = requestAnimationFrame(animation)
slider.classList.add('grabbing')
}
}
function touchEnd() {
isDragging = false
cancelAnimationFrame(animationID)
const movedBy = currentTranslate - prevTranslate
if (movedBy < -100 && currentIndex < slides.length - 1) currentIndex += 1
if (movedBy > 100 && currentIndex > 0) currentIndex -= 1
setPositionByIndex()
slider.classList.remove('grabbing')
}
function touchMove(event) {
if (isDragging) {
const currentPosition = getPositionX(event)
currentTranslate = prevTranslate + currentPosition - startPos
}
}
function getPositionX(event) {
return event.type.includes('mouse') ? event.pageX : event.touches[0].clientX
}
function animation() {
setSliderPosition()
if (isDragging) requestAnimationFrame(animation)
}
function setSliderPosition() {
slider.style.transform = `translateX(${currentTranslate}px)`
}
function setPositionByIndex() {
currentTranslate = currentIndex * -window.innerWidth
prevTranslate = currentTranslate
setSliderPosition()
} ```
Replace the <img/> tag with <video/> and replace the img reference in JS
HTML:
<div class="slider-container">
<div class="slide">
<h2>Airpods</h2>
<h4>$199</h4>
<video width="320" height="240" controls>
<source src="https://player.vimeo.com/external/367564948.sd.mp4?s=d969af3ae466e775628a8d281105fd03a8df12ae&profile_id=165&oauth2_token_id=57447761"/>
<video />
Buy Now
</div>
<div class="slide">
<h2>iPhone 12</h2>
<h4>$799</h4>
<video width="320" height="240" controls>
<source src="https://player.vimeo.com/external/334344435.sd.mp4?s=d367341a941ffa97781ade70e4f4a28f4a1a5fc8&profile_id=165&oauth2_token_id=57447761"/>
Buy Now
</div>
<div class="slide">
<h2>iPad</h2>
<h4>$599</h4>
<video width="320" height="240" controls>
<source src="https://player.vimeo.com/external/369639344.sd.mp4?s=b892fce959245aa4ae7ab08bc4b1af2766acdf4e&profile_id=165&oauth2_token_id=57447761"/>
Buy Now
</div>
</div>
CSS:
#import url('https://fonts.googleapis.com/css2?family=Open+Sans&display=swap');
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
font-family: 'Open Sans', sans-serif;
height: 100%;
width: 100%;
overflow: hidden;
background-color: #333;
color: #fff;
line-height: 1.7;
}
.slider-container {
height: 100vh;
display: inline-flex;
overflow: hidden;
transform: translateX(0);
transition: transform 0.3s ease-out;
cursor: grab;
}
.slide {
max-height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 1rem;
user-select: none;
}
.slide img {
max-width: 100%;
max-height: 60%;
transition: transform 0.3s ease-in-out;
}
.slide h2 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
}
.slide h4 {
font-size: 1.3rem;
}
.btn {
background-color: #444;
color: #fff;
text-decoration: none;
padding: 1rem 1.5rem;
}
.grabbing {
cursor: grabbing;
}
.grabbing .slide img {
transform: scale(0.9);
}
JS:
/*
This JS code is from the following project:
https://github.com/bushblade/Full-Screen-Touch-Slider
*/
const slider = document.querySelector('.slider-container'),
slides = Array.from(document.querySelectorAll('.slide'))
let isDragging = false,
startPos = 0,
currentTranslate = 0,
prevTranslate = 0,
animationID = 0,
currentIndex = 0
slides.forEach((slide, index) => {
const slideImage = slide.querySelector('video')
slideImage.addEventListener('dragstart', (e) => e.preventDefault())
// Touch events
slide.addEventListener('touchstart', touchStart(index))
slide.addEventListener('touchend', touchEnd)
slide.addEventListener('touchmove', touchMove)
// Mouse events
slide.addEventListener('mousedown', touchStart(index))
slide.addEventListener('mouseup', touchEnd)
slide.addEventListener('mouseleave', touchEnd)
slide.addEventListener('mousemove', touchMove)
})
// Disable context menu
window.oncontextmenu = function (event) {
event.preventDefault()
event.stopPropagation()
return false
}
function touchStart(index) {
return function (event) {
currentIndex = index
startPos = getPositionX(event)
isDragging = true
// https://css-tricks.com/using-requestanimationframe/
animationID = requestAnimationFrame(animation)
slider.classList.add('grabbing')
}
}
function touchEnd() {
isDragging = false
cancelAnimationFrame(animationID)
const movedBy = currentTranslate - prevTranslate
if (movedBy < -100 && currentIndex < slides.length - 1) currentIndex += 1
if (movedBy > 100 && currentIndex > 0) currentIndex -= 1
setPositionByIndex()
slider.classList.remove('grabbing')
}
function touchMove(event) {
if (isDragging) {
const currentPosition = getPositionX(event)
currentTranslate = prevTranslate + currentPosition - startPos
}
}
function getPositionX(event) {
return event.type.includes('mouse') ? event.pageX : event.touches[0].clientX
}
function animation() {
setSliderPosition()
if (isDragging) requestAnimationFrame(animation)
}
function setSliderPosition() {
slider.style.transform = `translateX(${currentTranslate}px)`
}
function setPositionByIndex() {
currentTranslate = currentIndex * -window.innerWidth
prevTranslate = currentTranslate
setSliderPosition()
}
I need to make a carousel/slideshow in plain JavaScript mixed with CSS that slides through the images one by one loop seamlessly.
I can't seem to get any code working. I've tried several approaches but can't. It's got to be with z-index, and not making use of flex.
This is my third attempt at coding this. Can't seem to get the logic. It has to have navigation buttons to switch between images. Can someone help me out?
const getHeader = document.querySelector('.wp-custom-header');
const getImages = document.querySelectorAll('.wp-custom-header img');
const computeImages = function () {
getImages.forEach((img, index) => {
if (index > 0) img.classList.add('out');
});
};
computeImages();
let counter = 0;
let reinit = false;
// getHeader.classList.add('transformSlide');
const slideShowTimer = setInterval(() => {
if (counter > 0 && counter < getImages.length - 1) {
getImages[counter + 1].classList.add('transform-slide');
getImages[counter + 1].classList.add('onqueue-current');
getImages[counter + 1].classList.remove('out');
} else if (counter === 0 && reinit === false) {
getImages[counter + 1].classList.add('transform-slide');
getImages[counter + 1].classList.add('onqueue-current');
getImages[counter + 1].classList.remove('out');
} else if (counter === 0 && reinit === true) {
getImages[counter].classList.add('transform-slide');
getImages[counter].classList.add('onqueue-current');
getImages[counter].classList.remove('out');
getImages[getImages.length - 1].classList.add('out');
getImages[getImages.length - 1].classList.remove('transform-slide');
getImages[getImages.length - 1].classList.remove('onqueue-current');
}
counter++;
}, 2000);
getHeader.addEventListener('transitionend', () => {
if (counter >= 1) {
if (!reinit) {
getImages[counter - 1].classList.remove('transform-slide');
getImages[counter - 1].classList.remove('onqueue-current');
getImages[counter - 1].classList.add('out');
} else {
getImages[counter].classList.remove('transform-slide');
getImages[counter].classList.remove('onqueue-current');
getImages[counter].classList.add('out');
}
}
if (counter >= getImages.length - 1) {
console.log(counter);
counter = 0;
reinit = true;
}
});
This is the HTML
<div id="wp-custom-header" class="wp-custom-header">
<img alt="" src="./image01.svg" />
<img alt="" src="./image02.svg" />
<img alt="" src="./image03.svg" />
<img alt="" src="./image04.svg" />
<img alt="" src="./image05.svg" />
<img alt="" src="./image06.svg" />
</div>
The CSS
.wp-custom-header {
position: relative;
display: block;
width: 100%;
height: var(--header-size);
}
.wp-custom-header img {
position: absolute;
display: block;
min-width: 100%;
-o-object-fit: cover;
object-fit: cover;
transition: var(--slide-transform) ease-in-out;
}
.wp-custom-header img.out {
/* left: -450px; */
z-index: 0;
transform: translateX(100%);
}
.wp-custom-header img.onqueue-next {
z-index: 0;
left: 0px;
}
.wp-custom-header img.onqueue-current {
z-index: 1;
transform: translateX(0px);
}
.transform-slide {
transition: var(--slide-transform) ease-in-out;
}
I took the liberty to tinker with your code. I've reworked your code into smaller functions and added a looping mechanic. Now you have buttons that will loop infinitely no matter how many slides there are in your carousel.
I've added a previous and a next button. Hovering over the images will stop the autoslide functionality from running so that you can control going to the next and previous slide. Whenever you stop hovering the carousel continues.
Hope that this is what you were looking for.
const header = document.querySelector('.wp-custom-header');
const images = document.querySelectorAll('.wp-custom-header img');
const buttons = document.querySelectorAll('.wp-custom-header button');
let activeSlideIndex = 0;
let interval = null;
const updateCarousel = () => {
images.forEach((image, index) => {
if (index === activeSlideIndex) {
image.classList.add('active');
} else if (image.classList.contains('active')) {
image.classList.remove('active');
}
});
};
const nextSlide = () => {
if (activeSlideIndex + 1 < images.length) {
activeSlideIndex++;
} else {
activeSlideIndex = 0;
}
};
const prevSlide = () => {
if (activeSlideIndex - 1 >= 0) {
activeSlideIndex--;
} else {
activeSlideIndex = images.length - 1;
}
};
const startInterval = () => setInterval(() => {
nextSlide();
updateCarousel();
}, 2000);
const stopInterval = () => {
clearInterval(interval);
interval = null;
};
interval = startInterval();
const controls = {
'prev': prevSlide,
'next': nextSlide
};
header.addEventListener('mouseenter', () => {
if (interval !== null) {
stopInterval();
}
});
header.addEventListener('mouseleave', () => {
interval = startInterval();
});
buttons.forEach(button => {
button.addEventListener('click', event => {
const value = event.target.value;
const action = controls[value];
action();
updateCarousel();
});
});
.wp-custom-header {
position: relative;
}
.wp-custom-header-images {
display: block;
width: 100%;
height: 250px;
}
.wp-custom-header-images img {
position: absolute;
display: block;
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
opacity: 0;
will-change: opacity;
transition: opacity 250ms ease-in-out;
z-index: 0;
}
.wp-custom-header-images img.active {
z-index: 1;
opacity: 1;
}
.wp-custom-header-button {
position: absolute;
top: 50%;
border: 1px solid #d0d0d0;
background-color: #f0f0f0;
border-radius: 50%;
width: 50px;
height: 50px;
cursor: pointer;
transform: translate(0, -50%);
z-index: 2;
}
.wp-custom-header-button[value="prev"] {
left: 15px;
}
.wp-custom-header-button[value="next"] {
right: 15px;
}
<div id="wp-custom-header" class="wp-custom-header">
<button class="wp-custom-header-button" value="prev">Prev</button>
<div class="wp-custom-header-images">
<img alt="" src="https://picsum.photos/seed/a/640/360" class="active" />
<img alt="" src="https://picsum.photos/seed/b/640/360" />
<img alt="" src="https://picsum.photos/seed/c/640/360" />
<img alt="" src="https://picsum.photos/seed/d/640/360" />
<img alt="" src="https://picsum.photos/seed/e/640/360" />
<img alt="" src="https://picsum.photos/seed/f/640/360" />
</div>
<button class="wp-custom-header-button" value="next">Next</button>
</div>
I'm being tormented in the past 4 hours to find out how to do this, I don't know what I'm doing wrong, I have a page with multiple layers, I wish to trigger some transition when the needed page has opacity 1, it should be simple when u think of it, here is my code, please help ;)
slide1 = document.querySelector('.slide1');
function videoPlay() {
var videoOne = document.getElementById('myVideo');
if ((slide1.style.opacity) > 0 ) {
videoOne.play();
}
}
videoPlay();
.slide {
width: 100%;
background-size: cover;
background-position: center;
position: absolute;
}
.slide1 {
width: 100%;
background: none;
opacity: 0;
}
<div class="slide slide1">
<div class="slide-content">
<div class="secondColumn">
<video muted id="myVideo">
<source src="Media/Acqua.mp4" type="video/mp4">
</video>
<div class="lowerTab"></div>
</div>
</div>
here is the code which i use to change the opacity using the wheel :
//wheel event
document.addEventListener('wheel',
function scrollWheel(event) {
var fig =event.deltaY;
if (fig > 0) {
slideMove();
}
else if (fig<0) {
slideMovReverse();
}
})
//basic movement
function slideMove() {
if (current === sliderImages.length-1 ) {
current = -1
}
reset();
sliderImages[current+1].style.transition = "opacity 1s ease-in 0s";
sliderImages[current+1].style.opacity= "1.0";
current++;
}
You can use the transitionend event, but you'd have to set up the transition first. As it sits now, there's not much information in your question about the different slides, how the transitions are set up, etc. Here's a baseline to give you an idea:
const slide1 = document.querySelector('.slide1');
const videoEl = document.querySelector('.slide1__video');
const button = document.querySelector('button');
let inView = false;
slide1.addEventListener('transitionend', () => {
let content = 'Playing';
if (inView) {
content = ''
}
videoEl.textContent = content;
inView = !inView;
})
button.addEventListener('click', () => {
slide1.classList.toggle('active')
})
.slide1 {
transition: opacity 500ms linear;
opacity: 0;
border: 1px solid green;
padding: 10px;
margin-bottom: 24px
}
.slide1.active {
opacity: 1
}
<div class="slide1">
Slide 1
<div class="slide1__video"></div>
</div>
<button>Next</button>
Edit
It'll need some love but I think it's in the right direction to what you're after.
const slides = Array.from(document.querySelectorAll('.slide'));
document.addEventListener('wheel', onScroll);
const SCROLL_TOLERANCE = 100;
let currentIndex = 0;
let currentScroll = 0;
function onScroll(e) {
if (e.deltaY > 0) {
currentScroll += 1;
} else {
currentScroll -= 1;
}
if (currentScroll >= (currentIndex * SCROLL_TOLERANCE) + 15) {
showNext();
} else if (currentScroll <= (currentIndex * SCROLL_TOLERANCE) - 15) {
showPrevious();
}
}
function showNext() {
if (currentIndex === slides.length - 1) {
return console.warn('At the end.');
}
currentIndex += 1;
setSlide();
}
function showPrevious() {
if (currentIndex === 0) {
return console.warn('At the beginning.');
}
currentIndex -= 1;
setSlide();
}
function setSlide() {
let newOpacity = 0;
slides.forEach(slide => {
if (+slide.dataset.index === currentIndex) {
newOpacity = 1
} else {
newOpacity = 0;
}
slide.style.opacity = newOpacity;
slide.addEventListener('transitionend', () => {
console.log('Done transitioning!');
// Do things here when the transition is over.
})
});
}
html,
body {
padding: 0;
margin: 0;
font-family: sans-serif;
font-size: 18px
}
.slide {
border: 3px solid #efefef;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
transition: all 500ms linear;
opacity: 0;
transition-delay: 250ms;
}
.slide.active {
opacity: 1;
}
<div class="slide active" data-index="0">
Slide 1
</div>
<div class="slide" data-index="1">
Slide 2
</div>
<div class="slide" data-index="2">
Slide 3
</div>
<div class="slide" data-index="3">
Slide 4
</div>
i need a new carousel for my website, for the mobile version.
so i created one using html css and javascript, but however, the switch between the images is way too "simple".
here is the code
The HTML
<div class="containerr">
<div style="display: inline-block;">
<img src="https://placeimg.com/400/200/people"/>
</div>
<div>
<img src="https://placeimg.com/400/200/any"/>
</div>
<div>
<img src="https://placeimg.com/400/200/nature"/>
</div>
<div>
<img src="https://placeimg.com/400/200/architecture"/>
</div>
<div>
<img src="https://placeimg.com/400/200/animals"/>
</div>
<div>
<img src="https://placeimg.com/400/200/people"/>
</div>
<div>
<img src="https://placeimg.com/400/200/tech"/>
</div>
</div>
CSS
}
.containerr {
max-width: 100%;
background-color: black;
margin: 0 auto;
text-align: center;
position: relative;
}
.containerr div {
background-color: white;
width: 100%;
display: inline-block;
display: none;
}
.containerr img {
width: 100%;
height: auto;
}
JS
var currentIndex = 0,
items = $('.containerr div'),
itemAmt = items.length;
function cycleItems() {
var item = $('.containerr div').eq(currentIndex);
items.hide();
item.css('display','inline-block');
}
var autoSlide = setInterval(function() {
currentIndex += 1;
if (currentIndex > itemAmt - 1) {
currentIndex = 0;
}
cycleItems();
}, 3000);
$('.next').click(function() {
clearInterval(autoSlide);
currentIndex += 1;
if (currentIndex > itemAmt - 1) {
currentIndex = 0;
}
cycleItems();
});
$('.prev').click(function() {
clearInterval(autoSlide);
currentIndex -= 1;
if (currentIndex < 0) {
currentIndex = itemAmt - 1;
}
cycleItems();
});
https://codepen.io/anon/pen/PmbrWj
looking for any tip to animate/transit the display:inline-block to display:none
You can build a fade in / out effect into your cycleItems() function:
function cycleItems() {
var visibleItem = items.filter(":visible");
var item = $('.containerr div').eq(currentIndex);
visibleItem.fadeOut(function() {
item.fadeIn();
});
}
The above code uses a jQuery filter to find the current visible item and calls fadeOut() on only that item. It then uses a callback function to execute fadeIn() on the current item after fadeOut() has completed.
Replace this items.hide();
with this items.fadeOut("slow");
I'm trying to fade in the h4 tags after the divs slides into view. Also I would like to add the class "current" to each slide in view. the fiddle http://jsfiddle.net/x8euhjrt/. code
<div class="slider">
<div class="slides">
<div class="slide slide-1">
<h4>Slide 1</h4>
</div>
<div class="slide slide-2">
<h4>slide 2</h4>
</div>
<div class="slide slide-3">
<h4>slide 3</h4>
</div>
<div class="slide slide-4">
<h4>slide 4</h4>
</div>
<div class="slide slide-1">
<h4>Slide 1</h4>
</div>
</div><!-- end homepage slider container -->
CSS:
.slider{
width: 550px;
background: #d00d00;
min-height: 385px;
overflow: hidden;
}
.slides{
width: 2750px;
margin: 0;
}
.slide{
position:relative;
display: block;
float: left;
width: 550px;
height:400px;
}
.slide-1{
background:#dedede;
}
.slide-2{
background:#999;
}
.slide-3{
background:#333;
}
.slide-4{
background:#555;
}
h4{
background:#bada55;
padding:15px 120px;
display: inline-block;
margin-top:30%;
font-size:1.4em;
}
jQuery:
$(document).ready(function(){
var width = 550;
var speed = 1000;
var pause = 3000;
var currentSlide = 1;
var $slider = $(".slider");
var $slides = $slider.find('.slides');
var $slide = $slider.find('.slide');
$slide.first().addClass('current');
//alert($slide.length);
setInterval(function(){
$slides.animate({'margin-left': '-='+ width}, speed, function(){
currentSlide++;
if (currentSlide === $slide.length) {
currentSlide = 1;
$slides.css('margin-left', 0);
}
});
}, pause);
});
Check out the demo here. I have modified the animate() function's callback argument.
$slides.animate({'margin-left': '-='+ width}, speed, function(){
currentSlide++;
$slide.removeClass("current");
if (currentSlide === $slide.length) {
currentSlide = 1;
$slides.css('margin-left', 0);
}
$slides.find("h4").hide();
$slide.eq(currentSlide-1).addClass("current");
$slide.eq(currentSlide-1).find("h4").fadeIn();
});
First update your css to hide the h4 inside the slide div
.slide h4 {
display:none;
}
Then do some changes in you query code
$(document).ready(function(){
var width = 550;
var speed = 1000;
var pause = 3000;
var currentSlide = 1;
var $slider = $(".slider");
var $slides = $slider.find('.slides');
var $slide = $slider.find('.slide');
$slide.first().addClass('current');
//fade in the first slide h4
$('.current h4').fadeIn();
setInterval(function(){
$slides.animate({'margin-left': '-='+ width}, speed, function(){
currentSlide++;
if (currentSlide === $slide.length) {
currentSlide = 1;
$slides.css('margin-left', 0);
}
//remove the class current from the element you added it previously
$('.slide').removeClass('current');
//add the class current by selecting the right element using the loop variable that stores the slide number
$('.slide-'+currentSlide).addClass('current');
//hide the h4 you previously fadeIn
$('.slide h4').hide();
//fadeIn the current slide h4
$('.current h4').fadeIn();
});
}, pause);
});