Jquery slideshow with multiple slideshows Interval not working - javascript

I've set up a jquery slideshow borrowing some code from someone else. I wanted to use the same logic to animate three slideshow panes at once (They should all move and pause at the same time)
However, when using the following code, only the third pane works as expected and I'm not sure why. Can anyone help explain why and look at fixing it?
It may be that I have to try a different method to achieve this, which is fine, but I'd like to at least understand what the problem is. I've got the working Jsfiddle here as well. What should happen is that each window should, after 10 seconds, move to the next slide, then after ten seconds it should go back to the original slide. Only the third window is doing this properly, the others are skipping the interval
<div class='windows'>
<div id='sliderWindow1' class='sliderWindow'>
<ul class='slidesWindow'>
<!-- Trend Graph -->
<li class='slideWindow'>
<div id='trendGraph'>Pane 1</div> <!--jscript to get chart -->
</li>
<!-- total number of votes -->
<li class='slideWindow'>
<div id='totalVotes'>Pane 2</div> <!--jscript to get chart -->
</li>
<li class='slideWindow'>
<div id='trendGraph2'>Pane 1</div> <!--jscript to get chart -->
</li>
</ul>
</div>
<div id='sliderWindow2' class='sliderWindow'>
<ul class='slidesWindow'>
<!-- Related Polls -->
<li class='slideWindow'>
<div id='related'>Pane 1b</div> <!--jscript to get chart -->
</li>
<!-- Likes -->
<li class='slideWindow'>
<div id='likesAndLiker'>Pane 2b</div> <!--jscript to get chart -->
</li>
<li class='slideWindow'>
<div id='relatedPolls2'>Pane 1b</div> <!--jscript to get chart -->
</li>
</ul>
</div>
<div id='sliderWindow3' class='sliderWindow'>
<ul class='slidesWindow'>
<!-- Your Vote -->
<li class='slideWindow'>
<div id='yourLike'>Pane 1c</div> <!--jscript to get chart -->
</li>
<!-- total number of votes -->
<li class='slideWindow'>
<div id='OtherThing'>Pane 2c</div> <!--jscript to get chart -->
</li>
<li class='slideWindow'>
<div id='yourLike2'>Pane 1c</div> <!--jscript to get chart -->
</li>
</ul>
</div>
</div>
Jscript
$(document).ready(function(){
//configuration
var width = 100;
var animationSpeed = 1000;
var pause = 12000;
var currentID = 0;
var currentSlide = 1;
var height = 100;
var StopCounting = true;
//cache DOM
var $Slider = $('.sliderWindow');
var $SlideContainer = $Slider.find(".slidesWindow");
var $Slides = $SlideContainer.find(".slideWindow");
var $SlidesLength = 3;
var interval;
$Slider.on('mouseenter', pauseSlider).on('mouseleave', startSlider);
//begin the slide show
startSlider();
function startSlider(){
//set interval
interval = setInterval(function(){
console.log(currentSlide + " of " + $SlidesLength);
//margin left -720
$SlideContainer.animate({'margin-left': '-='+width}, animationSpeed, function(){
//callback
currentSlide++;
currentID++;
//if this is the last slide go to position one (0px)
if(currentSlide === $SlidesLength){
currentSlide = 1;
$SlideContainer.css('margin-left', 0);
StopCounting = true;
}
});
}, pause);
}
//pause the slider by clearing the interval
function pauseSlider(){
clearInterval(interval);
}
});//end of document ready
CSS
.windows {
height: 200px;
width: 100%;
display: inline-block;
margin-top: 20px;
background-color: #C2F0FF;
}
.sliderWindow {
margin-left: 10%;
height: 100px;
/*width: 20%;*/
width: 100px;
background-color: #2EB8E6;
display: inline;
float: left;
overflow: hidden;
}
.slidesWindow{
display: block;
width: 300px;
height: 100px;
margin: 0;
padding: 0;
}
.slideWindow {
float: left;
list-style-type: none;
/*width: 100%;*/
width: 100px;
height: 100px;
}

From the JSfiddle, I could not figure out the exact response you are looking for. But I think I ran into a similar problem when I used multiple accordion elements in bootstrap/jquery the other day. The solution to the issue was to rename the div id and class id's the second and third time I was using the accordion. The analogy for you would be to check you div id and class id names and see if you can change their names in the second and third copies of the element.

I located the answer, the problem is where the "current slide" was adding up. This adds up for each slide that animates, and therefore "current slide" should start at 0 and Slide length should be equal to the number of slides times the number of windows.
Therefore the answer is:
$(document).ready(function(){
//configuration
var width = 100;
var animationSpeed = 1000;
var pause = 12000;
var currentID = 0;
var currentSlide = 0;
var height = 100;
var StopCounting = true;
//cache DOM
var $Slider = $('.sliderWindow');
var $SlideContainer = $Slider.find(".slidesWindow");
var $Slides = $SlideContainer.find(".slideWindow");
var $SlidesLength = 6;
var interval;
$Slider.on('mouseenter', pauseSlider).on('mouseleave', startSlider);
//begin the slide show
startSlider();
function startSlider(){
//set interval
interval = setInterval(function(){
//margin left -720
$SlideContainer.animate({'margin-left': '-='+width}, animationSpeed, function(){
//callback
currentSlide++;
currentID++;
alert(currentSlide);
//if this is the last slide go to position one (0px)
if(currentSlide === $SlidesLength){
currentSlide = 0;
$SlideContainer.css('margin-left', 0);
StopCounting = true;
}
});
}, pause);
}
//pause the slider by clearing the interval
function pauseSlider(){
clearInterval(interval);
}
});

Related

Problem with infinite loop in slider using jQuery

I tried making jQuery slider, which will pause on current image for couple of seconds and then move images horizontally. Also, when slider presents the last image in collection, slider should slowly get back to first image, or when marginLeft attribute reaches value of -200vw(it decreases gradually for -100vw after every image). Most of the time slider works perfectly, but there are also moments when slider ignores my if and goes above -200vw(sometimes up to -3000vw), resulting in showing no images. The only thing that I noticed in this situation is that this problem can occur after around 5-10 minutes spent on other browser tabs.
P.S I apologize for a lack of precise details, because these are the only thing I have noticed with this problem
jQuery/Javascript
$(document).ready(function() {
let delay = 5300;
let currentSlide = 1;
let $carousel = $('#carousel')
let $slideContainer = $carousel.find('.slides');
let $width = 100;
let $slides = $slideContainer.find('.slide')
var interval = setInterval(function() {
$slideContainer.animate({
'marginLeft': '-=' + $width + 'vw'
}, 1000, function() {
currentSlide++;
var abc = $slideContainer.width();
if (currentSlide == $slides.length) {
setTimeout(function() {
$slideContainer.animate({
'marginLeft': '+=' + ($width + 100) + 'vw'
}, 1000, function() {
currentSlide = 1;
$slideContainer.css({
'marginLeft': 0 + 'vw'
})
})
}, (delay / 2.5))
}
})
}, delay);
});
HTML
<section id="carousel">
<div class="slides">
<div class="slide">
<img src="../javaskript/images/slider/gaming1.jpg" style="height:100vh" alt="Introduction image 2 - slider" />
</div>
<div class="slide">
<img src="../javaskript/images/slider/gaming2.jpg" style="height:100vh" alt="Introduction image 2 - slider">
</div>
<div class="slide">
<img src="../javaskript/images/slider/scorn.jpg" style="height:100vh" alt="Introduction image 2 - slider">
</div>
</div>
</section>
CSS
#carousel {
overflow : hidden;
white-space : nowrap;
width : 300vw;
height : 100vh;
}
.slides {
display : flex;
width : 300vw;
margin : 0;
padding : 0;
}
.slide {
width : 100vw;
overflow : hidden;
}

How to create Image slideshow with slide left/right animation using javascript only?

I am working on simple solution which requires image slider.
Right now it is just fading in and out. i would like to add some slide animation
I can simply do it using jquery but i don't want to use any external libraries.
var counter = 0;
var slideImgs = [
"http://placesforkidsct.com/wp-content/uploads/2016/07/300x250.png",
"https://abbs.edu.in/wp-content/uploads/2018/01/self-development-300x140.jpg",
"https://abbs.edu.in/wp-content/uploads/2018/01/self-development-300x140.jpg"
]
var imgelm = document.getElementById("300x250_Image");
var inst = setInterval(change, 1500);
function change() {
// elem.innerHTML = text[counter];
imgelm.src = slideImgs[counter];
counter++;
if (counter >= slideImgs.length) {
counter = 0;
// clearInterval(inst); // uncomment this if you want to stop refreshing after one cycle
}
}
change();
<div class="300x250_section_3" style="float: left;margin-top: 13px;">
<div class="300x250_center_img" style="
width: 300px;
height:140px;
float: left;
">
<img src="http://placesforkidsct.com/wp-content/uploads/2016/07/300x250.png" style="width: 300px;text-align: center;display: block; margin:auto; max-height:140px;
" id="300x250_Image" class="slide_1">
</div>
</div>

Adding class names on hover based on conditions

I've created a tabbed module which works by getting content that is in the .content div (which is hidden) and displaying it in a empty div called .overview.
The idea behind this tabbed module is that, on hover (or when class active exists), the content on the right will change based on what header is being selected from the left. I.e. If I hover over a header named "Red", the .overview div on the right will spit out "red".
However, the issues I'm having are the following:
In the demo below, don't hover on any of the headers. The .overview div has no content - which is obviously not ideal. If .tabs has class .active, then I want its content displayed on the right. I have a counter running which changes class active every 5 seconds. I don't only want to show stuff on hover.
Having said the above, if I hover over another tabs div, I want the counter to stop - to prevent it from adding class active to another .tabs div (because the hovered on tabs is active.
Demo:
$(document).ready(function() {
// add class .active on li hover
$('.tabs').mouseenter(function() {
//$('.tabs').removeClass('active');
$(this).parents('.tabs').addClass('active');
});
// Change active tab every x seconds
$(function() {
var list = $(".tabs"),
currentActive = 0;
time = 5; // interval in seconds
setInterval(function() {
currentActive = (currentActive + 1) % list.length;
list.removeClass('active').eq(currentActive).addClass('active');
}, time * 1000);
});
})
var overview = $('.overview');
$('.tabs').each(function(i) {
var thisTab = $(this);
var thisContent = thisTab.find('.content').html();
// when class .active exists, change content in .overview
if ($('.tabs').hasClass('active')) {
overview.html(thisContent);
}
// on hover, change content in .overview
thisTab.on('mouseenter', function(e) {
thisTab.addClass('active');
overview.html(thisContent);
})
.on('mouseleave', function(e) {
thisTab.removeClass('active');
overview.html('');
});
});
.tabs.active {
background: none yellow;
}
.list {
flex-basis: 40%;
}
.list li {
list-style-type: none;
}
.overview {
flex-basis: 60%;
border: 1px solid blue;
}
.content {
display: none;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="d-flex flex-row">
<div class="list">
<li class="tabs active">
<div class="header"><span>Header</span></div>
<div class="content">
<p>Content 1</p>
</div>
</li>
<li class="tabs">
<div class="header"><span>Header 2</span></div>
<div class="content">
<p>Content 2</p>
</div>
</li>
<li class="tabs">
<div class="header"><span>Header 3</span></div>
<div class="content">
<p>Content 3</p>
</div>
</li>
</div>
<div class="overview"> </div>
</div>
Edit:
I've managed to make some movement on issue 1. I've added:
if ($('.tabs').hasClass('active')) {
overview.html(thisContent);
}
Which now, without hover, displays content in .overview, however, the content doesn't change when another tab is .active (i.e. in the demo, don't hover over anything, wait and it just shows content 3 for all headers.
I would do the following (I have commented what I have changed)
$(document).ready(function() {
var list = $(".tabs"),
overview = $('.overview'),
autoInterval, // interval var
currentActive = 0; // make this global to this closure
overview.html(list.eq(0).find('.content').html()); // set overview content
startInterval(); // start interval straight away
// add class .active on li hover
list.mouseenter(function() {
var thisTab = $(this);
currentActive = list.index(this); // set current active
list.removeClass('active'); // remove active class
thisTab.addClass('active'); // add active class
clearInterval(autoInterval); // clear the interval whilst hovering
var thisContent = thisTab.find('.content').html(); // get content
overview.html(thisContent); // set overview content
});
list.mouseleave(function() {
startInterval(); // restart the interval on mouseleave
});
function startInterval() {
// Change active tab every x seconds
time = 5; // interval in seconds
autoInterval = setInterval(function() {
currentActive = (currentActive + 1) % list.length;
list.removeClass('active');
var currentTab = list.eq(currentActive);
currentTab.addClass('active');
overview.html(currentTab.find('.content').html()); // set overview content
}, time * 1000);
}
});
.tabs.active {
background: none yellow;
}
.list {
flex-basis: 40%;
}
.list li {
list-style-type: none;
}
.overview {
flex-basis: 60%;
border: 1px solid blue;
}
.content {
display: none;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="d-flex flex-row">
<div class="list">
<li class="tabs active">
<div class="header"><span>Header</span></div>
<div class="content">
<p>Content 1</p>
</div>
</li>
<li class="tabs">
<div class="header"><span>Header 2</span></div>
<div class="content">
<p>Content 2</p>
</div>
</li>
<li class="tabs">
<div class="header"><span>Header 3</span></div>
<div class="content">
<p>Content 3</p>
</div>
</li>
</div>
<div class="overview"> </div>
</div>
As soon as you add the mouseenter event, you need to stop the interval, you have the method clearInterval to do so.

Carousel slides incorrectly when swiping or when clicking the slider controls (next/prev)

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>
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.
tru use Slick galleries, it is better amounth any galleries
http://kenwheeler.github.io/slick/
The following should fix your slide issue. I added some code to the CSS and JS ensuring the slide will move at one slide and worked on smaller screen resolution also.
The JS:
The CSS:
The HTML: I left it unchanged, so just use the same HTML you have. Best regards.
When setting/getting values in a collection of elements, it's best to use .map(). Here's the answer in 50 lines (view on CodePen):
$(".faculty-carousel").map(function() {
// Use that to refer to the child nodes of each carousel object instance
var that = $(this),
slides = that.find(".faculty-items li"),
carousel = that.find(".faculty-items"),
prevBtn = that.find(".prev"),
nextBtn = that.find(".next"),
slideLen = slides.length,
slideCount = slideLen - 1;
// Set reference point for carousel movements. The .is-active class will always
// be applied to the activeSlide, providing a reliable method for maintaining
// the carousel's state.
slides.first().addClass("is-active");
// Shift in response to user click. Accepts optional direction argument
var shiftCarousel = function(direction) {
var target = that.find(".is-active");
var currentSlide = target.attr("data-slide");
if (direction === "left" && currentSlide > 0) {
currentSlide--;
target.removeClass("is-active").prev().addClass("is-active");
}
if (direction === "right" && currentSlide < slideCount) {
currentSlide++;
target.removeClass("is-active").next().addClass("is-active");
}
var transformPercentage = -1 * currentSlide / slideLen * 100;
carousel.css("transform", "translateX(" + transformPercentage + "% )");
};
var x = 0;
// Get position of each slide and store it in an HTML attribute
slides.each(function() {
$(this).attr("data-slide", "" + x++ + "");
$(this).click(function() {
$(this).addClass("is-active").siblings().removeClass("is-active");
// Invoke shiftCarousel() without a parameter
shiftCarousel();
});
});
// Invoke shiftCarousel() with a parameter
prevBtn.on("click", function() {
shiftCarousel("left");
});
nextBtn.on("click", function() {
shiftCarousel("right");
});
// to manage mobile events, you can reference events via Hammer API
// or JavaScript's built-in touchstart, touchcancel etc. events i.e.
// prevBtn.on('touchstart', function() {
// do something
// });
});
It's better to stick with jQuery here. Oluwafunmito's solution uses innerHTML, which is the only practical technique if using vanilla JS. However, innerHTML can inadvertently expose your website visitors to an XSS attack and should be avoided whenever possible.
You can use swiper. most modern mobile touch slider with hardware accelerated transitions and amazing native behaviour.
Instead of going through your whole code I can provide you with a fully functional carousel code using bootstrap and JavaScript. maybe this will give a hint about where your program is lacking and a bit of help in unerring your code.
<div id="mycarousel" class="carousel slide" data-interval="3000" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#mycarousel" data-slide-to="0" class="active"></li>
<li data-target="#mycarousel" data-slide-to="1"></li>
<li data-target="#mycarousel" data-slide-to="2"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img class="img-responsive"
src="img/uthappizza.png" alt="Uthappizza">
<div class="carousel-caption">
<h2>Uthappizza <span class="label label-danger">Hot</span> <span class="badge">$4.99</span></h2>
<p>A unique combination of Indian Uthappam (pancake) and
Italian pizza, topped with Cerignola olives, ripe vine
cherry tomatoes, Vidalia onion, Guntur chillies and
Buffalo Paneer.</p>
<p><a class="btn btn-primary btn-xs" href="#">More »</a></p>
</div>
</div>
<div class="item">
<img class="media-object img-thumbnail"
src="img/buffet.png" alt="Buffet">
<div class="carousel-caption">
<h2>Weekend Grand Buffet <span class="label label-danger">New</span> </h2>
<p>Featuring mouthwatering combinations with a choice of five different salads,
six enticing appetizers, six main entrees and five choicest desserts.
Free flowing bubbly and soft drinks. All for just $19.99 per person</p>
<p><a class="btn btn-primary btn-xs" href="#">More »</a></p>
</div>
</div>
<div class="item">
<img class="media-object img-thumbnail"
src="img/alberto.png" alt="Alberto Somayya">
<div class="carousel-caption">
<h2 >Alberto Somayya</h2>
<h4>Executive Chef</h4>
<p>Award winning three-star Michelin chef with wide
International experience having worked closely with
whos-who in the culinary world, he specializes in
creating mouthwatering Indo-Italian fusion experiences.
</p>
<p><a class="btn btn-primary btn-xs" href="#">More »</a></p>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#mycarousel" 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="#mycarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
<div class="btn-group" id="carouselButtons">
<button class="btn btn-danger btn-sm" id="carousel-pause">
<span class="fa fa-pause" aria-hidden="true"></span>
</button>
<button class="btn btn-danger btn-sm" id="carousel-play">
<span class="fa fa-play" aria-hidden="true"></span>
</button>
</div>
</div>
</div>
JavaScript
<script>
$('.carousel').carousel('pause')
</script>
<script>
$(".btn-group > .btn").click(function(){
$(this).addClass("active").siblings().removeClass("active");
});
</script>
<script>
$(document).ready(function(){
//$("#mycarousel").carousel( { interval: 2000 } );
$("#carousel-pause").click(function(){
$("#mycarousel").carousel('pause');
});
$("#carousel-play").click(function(){
$("#mycarousel").carousel('cycle');
});
});
</script>
credits:coursera
Your using the .each on all of the slides on all of the carousels, setting up a pan event and animation for each slide. Try only binding your function (and the included pan) on $('.faculty-carousel').each

Improve slide effect

I have created a simple slider
html
<div id="sldvid1" class="slider" >
<img picnum="1" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail1.png" />
<img picnum="2" style="display:none;" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail7.png" />
<img picnum="3" style="display:none;" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail14.png" />
</div>
<hr>
<div id="sldvid2" class="slider" >
<img picnum="1" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail1.png" />
<img picnum="2" style="display:none;" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail7.png" />
<img picnum="3" style="display:none;" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail14.png" />
</div>
$
var timer1 = setInterval(runSlide, 1000);
var curnum = 1;
function runSlide()
{
curnum = $(".slider img:visible").attr('picnum');
//$("#sldvid1 img[picnum=" + curnum + "]").fadeOut();
if(curnum == 3){
curnum = 1;
}
else
{
curnum++;
}
// $(".slider img").hide();
//$(".slider img[picnum=" + curnum + "]").show();
$(".slider img").hide();
$(".slider img[picnum=" + curnum + "]").show();
//console.log(curnum);
}
CSS
.slider{
height:50px;
}
Demo
http://jsfiddle.net/mparvez1986/vf401e2y/
Everything is working fine, I just need some one to improve effect so that it could effect like moving from left to right, I tried with some effect, but it seems it required some css manipulation as well
Thanks
I modified your code to create a carousel where images are slid in and out. I accomplished this by animating the margin-left CSS property with jQuery. I specified a size for the .slider class and used overflow: hidden; to ensure the sliding images were not displayed outside of it.
If you wish, you can change the transition effect by changing the CSS property that is animated and ensuring that the elements are in the correct position for the animation before it begins.
You can also change the speed of the animation by changing the magic number 1000 that I've left in the calls to animate. This number is specified in milliseconds.
By the way, I should point out that while custom HTML attributes are allowed in HTML5 they should begin with data-; they are called data attributes.
jsfiddle
HTML
<div id="sldvid1" class="slider">
<img class="active" data-slide-to="0" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail1.png"/>
<img data-slide-to="1" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail7.png"/>
<img data-slide-to="2" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail14.png"/>
</div>
<hr>
<div id="sldvid2" class="slider">
<img class="active" data-slide-to="0" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail1.png"/>
<img data-slide-to="1" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail7.png"/>
<img data-slide-to="2" src="https://s3.amazonaws.com/qa.SentientPrime.media/Ecommerce/44c068f106659d396f1ea0f2401f3879/1/thumbnail14.png"/>
</div>
CSS
.slider {
position: relative;
width: 50px;
height: 50px;
overflow: hidden;
}
.slider img {
display: none;
width: 100%;
position: absolute;
}
.slider .active {
display: inline-block;
}
.slider .sliding {
display: inline-block;
}
JavaScript
var timer = setInterval(runSlide, 2000);
function runSlide() {
// Slide each slider on the page.
$(".slider").each(function (index, element) {
// Get the elements involved in the slide.
var numChildren = $(this).children().length;
var activeChild = $(this).children(".active");
var activeSlideTo = $(activeChild).attr("data-slide-to");
var nextSlideTo = (parseInt(activeSlideTo) + 1) % numChildren;
var nextChild = $(this).find("*[data-slide-to=" + nextSlideTo + "]");
// Prepare for slide.
$(activeChild).css("margin-left", "0%");
$(nextChild).css("margin-left", "-100%");
$(activeChild).addClass("sliding");
$(nextChild).addClass("sliding");
$(activeChild).removeClass("active");
// Slide using CSS margin-left.
$(activeChild).animate({"margin-left": "100%"}, 1000, function () {
$(this).removeClass("sliding");
});
$(nextChild).animate({"margin-left": "0%"}, 1000, function () {
$(this).addClass("active");
$(this).removeClass("sliding");
});
});
}
Ended with following
setInterval(function() {
$('#sldvid1 > img:first')
.fadeOut(1000)
.next()
.fadeIn(1000)
.end()
.appendTo('#sldvid1');
}, 3000);

Categories