I've just finished building a carousel I've been working on that uses swipe/touch and also uses controls such as prev/next to control the carousel. Right now I'm having an issue regarding about the carousel behavior. Basically I'm trying to make it slide one by one. Here is a sample of the code I've been working on. Right now it seems to be sliding by 2 or 3 depending on how many carousel I've placed.
I'm also having an issue with regards to making it responsive also
function fCarousel() {
// var activeSlide = 0;
// $('.faculty-carousel').attr('data-slide', '0');
var viewPortSize = $(window).width(),
facultyPanel = $('.faculty-carousel .faculty-items li'),
profileCount = facultyPanel.length,
activeSlide = 0,
carousel = $('.faculty-carousel .faculty-items');
$('.faculty-carousel').attr('data-slide', '0');
//Set Panel Size based on viewport
if (viewPortSize <= 1920 ) {
var profilePanelSize = viewPortSize / 5
}
if (viewPortSize < 1024 ) {
var profilePanelSize = viewPortSize / 4
}
if (viewPortSize < 768 ) {
var profilePanelSize = viewPortSize / 3
}
if (viewPortSize < 480 ) {
var profilePanelSize = viewPortSize
}
carousel.outerWidth( profilePanelSize * profileCount );
facultyPanel.outerWidth(profilePanelSize);
carousel.css('transform', 'translateX(' + 0 + '% )');
$('.prev').on('click', function(e) {
event.stopPropagation();
var carouselWrapper = $(this).closest('.faculty-carousel'),
facultyProfilePanel = carouselWrapper.find('.faculty-items li'),
facultyProfileCount = facultyProfilePanel.length,
viewPortSize = $(window).width(),
carousel = carouselWrapper.find('.faculty-items'),
position = 0,
currentSlide = parseInt(carouselWrapper.attr('data-slide'));
// Check if data-slide attribute is greater than 0
if (currentSlide > 0) {
// Decremement current slide
currentSlide--;
// Assign CSS position to clicked slider
var transformPercentage = -1 * currentSlide / facultyProfileCount * 100;
carousel.css('transform', 'translateX(' + transformPercentage + '% )');
// Update data-slide attribute
carouselWrapper.attr('data-slide', currentSlide);
activeSlide = currentSlide;
}
});
$('.next').on('click', function(e) {
event.stopPropagation();
// store variable relevent to clicked slider
var carouselWrapper = $(this).closest('.faculty-carousel'),
facultyProfilePanel = carouselWrapper.find('.faculty-items li'),
facultyProfileCount = facultyProfilePanel.length,
viewPortSize = $(window).width(),
carousel = carouselWrapper.find('.faculty-items'),
position = 0,
currentSlide = parseInt(carouselWrapper.attr('data-slide'));
// Check if dataslide is less than the total slides
if (currentSlide < facultyProfileCount - 1) {
// Increment current slide
currentSlide++;
// Assign CSS position to clicked slider
var transformPercentage = -1 * currentSlide / facultyProfileCount * 100;
carousel.css('transform', 'translateX(' + transformPercentage + '% )');
// Update data-slide attribute
carouselWrapper.attr('data-slide', currentSlide);
activeSlide = currentSlide;
}
})
$('.faculty-carousel .faculty-items').each(function() {
// create a simple instance
// by default, it only adds horizontal recognizers
var direction;
var touchSlider = this;
var mc = new Hammer.Manager(this),
itemLength = $(this).find('li').length,
count = 0,
slide = $(this),
timer;
var sliderWrapper = slide,
slideItems = sliderWrapper.find('li'),
//slider = sliderWrapper.find('li'),
totalPanels = slideItems.length,
currentSlide = parseInt(sliderWrapper.attr('data-slide'));
// mc.on("panleft panright", function(ev) {
// direction = ev.type;
// });
mc.add(new Hammer.Pan({
threshold: 0,
pointers: 0
}))
mc.on('pan', function(e) {
var percentage = 100 / totalPanels * e.deltaX / window.innerWidth;
var transformPercentage = percentage - 100 / totalPanels * activeSlide;
touchSlider.style.transform = 'translateX( ' + transformPercentage + '% )';
var sliderWrapper = $(e.target).closest('.faculty-carousel')
if (e.isFinal) { // NEW: this only runs on event end
var newSlide = activeSlide;
if (percentage < 0)
newSlide = activeSlide + 1;
else if (percentage > 0)
newSlide = activeSlide - 1;
goToSlide(newSlide, sliderWrapper);
}
});
var goToSlide = function(number, sliderWrapper) {
if (number < 0)
activeSlide = 0;
else if (number > totalPanels - 1)
activeSlide = totalPanels - 1
else
activeSlide = number;
sliderWrapper.attr('data-slide', activeSlide);
touchSlider.classList.add('slide-animation');
var percentage = -(100 / totalPanels) * activeSlide;
touchSlider.style.transform = 'translateX( ' + percentage + '% )';
timer = setTimeout(function() {
touchSlider.classList.remove('slide-animation');
}, 400);
};
});
}
$(document).ready(function() {
fCarousel();
})
$(window).on('resize', function(){
fCarousel();
})
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
.faculty-items li {
height : 100px;
}
.faculty-items li:nth-child(odd) {
background-color : grey;
}
.faculty-items li:nth-child(even) {
background-color : aqua
}
.faculty-items {
overflow : hidden;
position : relative;
right : 0;
display : flex;
-webkit-transition: transform 0.3s linear;
}
.faculty-carousel .controls {
display : block;
}
<!doctype html>
<html>
<head>
<title>Carousel</title>
<link rel="stylesheet" href="style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
</head>
<body>
<div class="faculty-carousel">
<ul class="faculty-items">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
<div class="controls">
<div class="prev">
prev
</div>
<div class="next">
next
</div>
</div>
</div>
<div class="faculty-carousel">
<ul class="faculty-items">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
<div class="controls">
<div class="prev">
prev
</div>
<div class="next">
next
</div>
</div>
</div>
<div class="faculty-carousel">
<ul class="faculty-items">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
<div class="controls">
<div class="prev">
prev
</div>
<div class="next">
next
</div>
</div>
</div>
</body>
</html>
In browsers where the Page Visibility API is supported, the carousel will avoid sliding when the webpage is not visible to the user (such as when the browser tab is inactive, the browser window is minimized, etc.).
To turn off the autoplay set data-interval="false" to the carousel element.
click(function(){ alert("Clicked."); $('#myCarousel'). carousel({ pause: true, interval: false }); });
A carousel slider is a slideshow of photos in WordPress. Adding visuals such as photos and videos to a website gets visitors' attention. It also enhances the user experience. For a design or photographer website, placing images in sliders or photo carousels makes them more interactive.
Okay, my first answer here was done in a hurry but I believe I have a clear JavaScript representation of what most modern Carousels would function like, although the rest is up to you if you choose to use it.
Here is the JavaScript side of things well explained
// Index all Carousel
for (var i = 0; i < document.getElementsByClassName("carousel").length; i++) {
// Create a container for all the slides
document.getElementsByClassName("carousel")[i].innerHTML = (
'<div class="slides-container">' +
document.getElementsByClassName("carousel")[i].innerHTML +
'</div>'
);
// If the Carousel is automated
if (document.getElementsByClassName("carousel")[i].getAttribute("data-auto")) {
// Remove all white-space in the Carousel's "data-auto" attribute.
document.getElementsByClassName("carousel")[i].setAttribute("data-auto", document.getElementsByClassName("carousel")[i].getAttribute("data-auto").replace(/ /g, ""));
// Set the Carousel direction
document.getElementsByClassName("carousel")[i]._direction = String(document.getElementsByClassName("carousel")[i].getAttribute("data-auto").slice(0, document.getElementsByClassName("carousel")[i].getAttribute("data-auto").indexOf("_")));
// Set the Carousel interval
document.getElementsByClassName("carousel")[i]._interval = (parseFloat(document.getElementsByClassName("carousel")[i].getAttribute("data-auto").slice(document.getElementsByClassName("carousel")[i].getAttribute("data-auto").indexOf("_")).replace("_", "")) * 1000)
};
// Index all Carousel slides
for (var j = 0; j < document.getElementsByClassName("carousel")[i].querySelector(".slides-container").children.length; j++)
// Hide them
document.getElementsByClassName("carousel")[i].querySelector(".slides-container").children[j].hidden = true;
// Show the first one or the specified slide
document.getElementsByClassName("carousel")[i].querySelector(".slides-container").children[(parseInt(document.getElementsByClassName("carousel")[i].getAttribute("data-active")) || 0)].hidden = false;
// Carousel Next
document.getElementsByClassName("carousel")[i]._next = function() {
// Index all Carousel Slides
for (var j = 0; j < this.querySelector(".slides-container").children.length; j++)
// Show the next slide in the set
if (this.querySelector(".slides-container").children[j].hidden == false) {
this.querySelector(".slides-container").children[j].hidden = true;
(this.querySelector(".slides-container").children[j].nextElementSibling || this.querySelector(".slides-container").children[0]).hidden = false;
break
}
};
// Carousel Previous
document.getElementsByClassName("carousel")[i]._prev = function() {
// Index all Carousel Slides
for (var j = 0; j < this.querySelector(".slides-container").children.length; j++)
// Show the previous slide in the set
if (this.querySelector(".slides-container").children[j].hidden == false) {
this.querySelector(".slides-container").children[j].hidden = true;
(this.querySelector(".slides-container").children[j].previousElementSibling || this.querySelector(".slides-container").children[this.querySelector(".slides-container").children.length - 1]).hidden = false;
break
}
};
// Carousel Toggle
document.getElementsByClassName("carousel")[i]._toggle = function(slideIndex) {
// Index all Carousel Slides
for (var j = 0; j < this.querySelector(".slides-container").children.length; j++)
// Hide them
this.querySelector(".slides-container").children[j].hidden = true;
// Show the specified slide
(this.querySelector(".slides-container").children[slideIndex] || document.createElement("div")).hidden = false
};
// If the Carousel Interval is a Number
if (typeof document.getElementsByClassName("carousel")[i]._interval == "number") {
// Index
var index = i;
// Set an interval to automate the Carousel
setInterval(function() {
// If the Carousel direction is right
if (document.getElementsByClassName("carousel")[index]._direction == "right")
document.getElementsByClassName("carousel")[index]._next();
// If the Carousel direction is left
else if (document.getElementsByClassName("carousel")[index]._direction == "left")
document.getElementsByClassName("carousel")[index]._prev()
}, document.getElementsByClassName("carousel")[i]._interval)
}
// If the Carousel has buttons
if (document.getElementsByClassName("carousel")[i].hasAttribute("data-buttons"))
// Make the Buttons Container
document.getElementsByClassName("carousel")[i].innerHTML += (
'<div class="buttons-container">' +
'<button onclick="this.parentNode.parentNode._prev()"> Previous </button>' +
'<button onclick="this.parentNode.parentNode._next()"> Next </button>' +
'</div>'
)
// If the Carousel has indicators
if (document.getElementsByClassName("carousel")[i].hasAttribute("data-indicators"))
// Make the Indicators Container
document.getElementsByClassName("carousel")[i].innerHTML += (
'<div class="indicators-container">' +
// Place as many checkboxes for as many slides there are
(function() {
var indicators = "";
for (var k = 0; k < document.getElementsByClassName("carousel")[i].querySelector(".slides-container").children.length; k++)
indicators += (
'<input class="indicator-' + k + '" onclick="this.parentNode.parentNode._toggle(this.getAttribute(\'class\')[this.getAttribute(\'class\').length - 1])" type="checkbox">'
);
return indicators
})() +
'</div>'
);
// Add a click event to the Carousel
document.getElementsByClassName("carousel")[i].addEventListener("click", function() {
// Index all Carousel
for (var j = 0; j < document.getElementsByClassName("carousel").length; j++)
// If the Carousel indexed is not the target Carousel
if (document.getElementsByClassName("carousel")[j] != this)
// Blur it
document.getElementsByClassName("carousel")[j].removeAttribute("data-focus");
else
// 'Focus' it
document.getElementsByClassName("carousel")[j].setAttribute("data-focus", "")
// If the mouse click is to the left of the carousel
if (event.clientX < (this.getBoundingClientRect().left + (this.getBoundingClientRect().width / 2)))
this._prev();
// If the mouse click is to the right of the carousel
else if ((event.clientX > (this.getBoundingClientRect().left + (this.getBoundingClientRect().width / 2))))
this._next()
})
};
// Attach an event to the <body>.
document.body.addEventListener("keydown", function() {
switch (event.code) {
// If the left arrow key is pressed
case "ArrowLeft":
document.querySelector(".carousel[data-focus")._prev();
break;
// If the right arrow key is pressed
case "ArrowRight":
document.querySelector(".carousel[data-focus")._next();
break;
}
})
in this section of the code for the Carousel, the .hidden
property can be replaced with anything else but it gives a basic idea of how the slides pass on through the active and inactive states.
as for the HTML part
<html>
<body>
<div class="carousel" data-active="1" data-auto="right_1" data-buttons data-indicators style="height: 300px">
<div style="background: #F00; color: #FFF; font-size: 50px; height: 100%; line-height: 300px; text-align: center"> R </div>
<div style="background: #0F0; color: #FFF; font-size: 50px; height: 100%; line-height: 300px; text-align: center"> G </div>
<div style="background: #00F; color: #FFF; font-size: 50px; height: 100%; line-height: 300px; text-align: center"> B </div>
</div>
<!-- The JS script for the Carousel -->
<script src="carousel.js"> </script>
</body>
</html>
Everything has been simplified:
the class
of carousel
to make a new Carousel,
data-active
attribute to state which slide is active (starts from 0
),
the data-auto
attribute which specifies if the Carousel is automated or not (the right_
stands for the direction the automation and the _1
for how long the interval is),
the data-buttons
attribute if buttons are required,
data-indicators
if Carousel indicators are required and
the slides as the children of the Carousel.
So yes, this is pretty much the HTML/JS code required for building a simple Carousel.
In case you're looking for anything exciting going on in the world of JavaScript, there is a library I'm working on that I think you might be interested in: https://github.com/LapysDev/LapysJS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With