slider with jQuery - javascript

can u help me to adjust my code to make infinite slider? I tried on my own but when I changed conditions I got the problem with proper working.. just want to make it go from the last slide to first when the limit of slides is reached.. this is my code in JS
var nextBtn = $('.next_btn');
var prevBtn = $('.prev_btn');
var allSlides = $('.slide');
var indexSlide = 0;
$(allSlides[indexSlide]).addClass('visible');
nextBtn.on('click', function(){
if (indexSlide >= allSlides.length - 1) {
indexSlide = allSlides.length - 1;
} else {
$(allSlides[indexSlide]).removeClass('visible');
indexSlide++;
$(allSlides[indexSlide]).addClass('visible');
}
})
prevBtn.on('click', function(){
if (indexSlide <=0) {
indexSlide = 0;
} else {
$(allSlides[indexSlide]).removeClass('visible');
indexSlide--;
$(allSlides[indexSlide]).addClass('visible');
}
})

hide slide,
increment/decrement index
check whether it's in range (otherwise set proper value)
show new slide
var nextBtn = $('.next_btn');
var prevBtn = $('.prev_btn');
var allSlides = $('.slide');
var indexSlide = 0;
var lastIndex = allSlides.length - 1;
$(allSlides[indexSlide]).addClass('visible');
nextBtn.on('click', function() {
$(allSlides[indexSlide]).removeClass('visible');
indexSlide++;
if (indexSlide > lastIndex) {
indexSlide = 0;
}
$(allSlides[indexSlide]).addClass('visible');
})
prevBtn.on('click', function() {
$(allSlides[indexSlide]).removeClass('visible');
indexSlide--;
if (indexSlide < 0) {
indexSlide = lastIndex;
}
$(allSlides[indexSlide]).addClass('visible');
})
.slide {
display: none;
}
.slide.visible {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="prev_btn">Prev</button>
<button class="next_btn">Next</button>
<div class="slide">1</div>
<div class="slide">2</div>
<div class="slide">3</div>

Related

After 2 images slided in right side, next page is blank

I want to build a slider with buttons and I can`t figure out how should I do it.
When I hit the right button it slides 2 pages then show a blank, and thinking the problem is on the arrowRight function.
If anyone knows why my code isn't working please explain to me.
//FOR SLIDER
let sliderImages = document.querySelectorAll(".slide"),
arrowLeft = document.querySelector("#arrow-left"),
arrowRight = document.querySelector("#arrow-right"),
current = 0;
function reset() {
for (let i = 0; i < sliderImages.length; i++) {
sliderImages[i].style.display = 'none';
}
}
function startSlide() {
reset();
sliderImages[0].style.display = 'block';
}
startSlide();
function slideLeft() {
reset();
sliderImages[current - 1].style.display = 'block';
current--
}
arrowLeft.addEventListener('click', function () {
if (current === 0) {
current = sliderImages.length;
}
slideLeft();
})
function slideRight() {
reset();
sliderImages[current + 1].style.display = 'block';
current++
}
arrowRight.addEventListener('click', function () {
if (current === sliderImages.length) {
current = 0;
}
slideRight();
})
I don't think your method is perfect for that task. Usually it's two containers - one for visible part, other is full of images. It'll look something like this:
const sliderImages = document.querySelectorAll(".slide"),
arrowLeft = document.querySelector("#arrow-left"),
arrowRight = document.querySelector("#arrow-right"),
container = document.querySelector(".container");
document.addEventListener("DOMContentLoaded", function() {
container.style.width = 100 * sliderImages.length + "%";
sliderImages.forEach((el) => {
el.style.width = 100 / sliderImages.length + "%";
})
startSlider()
});
function startSlider() {
let pos = 0;
arrowLeft.addEventListener("click", slideLeft)
arrowRight.addEventListener("click", slideRight)
function slideLeft() {
if(pos === 0) {
pos = sliderImages.length - 1;
} else{
pos--;
}
slide()
}
function slideRight() {
if(pos === sliderImages.length - 1) {
pos = 0;
} else {
pos++;
}
slide()
}
function slide() {
$(container).animate({left: -100 * pos + "%"}, 500)
}
}
*{
padding: 0;
margin: 0;
}
body{
width: 100%;
}
.outer-container {
width: 80%;
margin: 5px auto;
overflow: hidden;
position: relative;
}
.slide > img {
width: 100%;
}
.container {
display: flex;
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer-container">
<div id="arrow-left">LEFT</div>
<div id="arrow-right">RIGHT</div>
<div class="container">
<div class="slide">
<img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80">
</div>
<div class="slide">
<img src="https://cdn.pixabay.com/photo/2017/02/20/18/03/cat-2083492_960_720.jpg">
</div>
<div class="slide">
<img src="https://media.boingboing.net/wp-content/uploads/2019/02/cats.jpg">
</div>
<div class="slide">
<img src="https://cdn-images-1.medium.com/max/1600/1*mONNI1lG9VuiqovpnYqicA.jpeg">
</div>
</div>
</div>
If you just a fix for your code, here's what I've changed:
arrowRight.addEventListener('click', function () {
//Make sure that's current less than the number of images
if (current + 1 == sliderImages.length) {
current = 0;
} else {
current++;
}
slide();
})
//Moved checks and current position management from slide
//Functions to click listeners
arrowLeft.addEventListener('click', function () {
if (current === 0) {
current = sliderImages.length - 1;
} else {
current--;
}
slide();
})
//That let me merge your two function into one
//And your checks for positions was a little off
function slide(){
reset();
sliderImages[current].style.display = 'block';
}
I hope my answer helped you. If you have any questions about this code add a comment below.

Make Fullpage-Scroll-Script less static

Heyo,
I got a little Fullpage-Scroll-Script and I want to make it a bit less static. So instead of calling every single Div by a different Class (.one, .two, .tree...) I want to make the script work if all Divs have only one Class (.page). I tried it myself with the .each() function from jQuery ... but I couldn't get it to work.
Here is the current Script:
// Fullpage Scroll Script
function ScrollHandler(pageClass) {
var page = $('.' + pageClass);
var pageStart = page.offset().top;
var pageJump = false;
function scrollToPage() {
pageJump = true;
$('html, body').animate({
scrollTop: pageStart
}, {
duration: 1000,
easing:'swing',
complete: function() {
pageJump = false;
}
});
}
window.addEventListener('wheel', function(event) {
var viewStart = $(window).scrollTop();
if (!pageJump) {
var pageHeight = page.height();
var pageStopPortion = pageHeight / 2;
var viewHeight = $(window).height();
var viewEnd = viewStart + viewHeight;
var pageStartPart = viewEnd - pageStart;
var pageEndPart = (pageStart + pageHeight) - viewStart;
var canJumpDown = pageStartPart >= 0;
var stopJumpDown = pageStartPart > pageStopPortion;
var canJumpUp = pageEndPart >= 0;
var stopJumpUp = pageEndPart > pageStopPortion;
var scrollingForward = event.deltaY > 0;
if ( ( scrollingForward && canJumpDown && !stopJumpDown) || (!scrollingForward && canJumpUp && !stopJumpUp)) {
event.preventDefault();
scrollToPage();
}
} else {
event.preventDefault();
}
});
}
new ScrollHandler('one');
new ScrollHandler('two');
new ScrollHandler('three');
* {
margin:0;
padding:0;
}
.page {
height: 100vh;
}
.one { background-color: blue; }
.two { background-color: green; }
.three { background-color: orange; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="page one"></div>
<div class="page two"></div>
<div class="page three"></div>
So instead of using:
new ScrollHandler('one');
new ScrollHandler('two');
new ScrollHandler('three');
I tried to use this:
$('.page').each(function() {
new ScrollHandler('page');
}
But it only worked for the first Div.
You need to pass $(this) in each loop and change the page variable to get directly the parameter :
// Fullpage Scroll Script
function ScrollHandler(pageClass) {
var page = pageClass;
var pageStart = page.offset().top;
var pageJump = false;
function scrollToPage() {
pageJump = true;
$('html, body').animate({
scrollTop: pageStart
}, {
duration: 1000,
easing: 'swing',
complete: function() {
pageJump = false;
}
});
}
window.addEventListener('wheel', function(event) {
var viewStart = $(window).scrollTop();
if (!pageJump) {
var pageHeight = page.height();
var pageStopPortion = pageHeight / 2;
var viewHeight = $(window).height();
var viewEnd = viewStart + viewHeight;
var pageStartPart = viewEnd - pageStart;
var pageEndPart = (pageStart + pageHeight) - viewStart;
var canJumpDown = pageStartPart >= 0;
var stopJumpDown = pageStartPart > pageStopPortion;
var canJumpUp = pageEndPart >= 0;
var stopJumpUp = pageEndPart > pageStopPortion;
var scrollingForward = event.deltaY > 0;
if ((scrollingForward && canJumpDown && !stopJumpDown) || (!scrollingForward && canJumpUp && !stopJumpUp)) {
event.preventDefault();
scrollToPage();
}
} else {
event.preventDefault();
}
});
}
$('.page').each(function() {
new ScrollHandler($(this));
})
* {
margin: 0;
padding: 0;
}
.page {
height: 100vh;
}
.one {
background-color: blue;
}
.two {
background-color: green;
}
.three {
background-color: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="page one"></div>
<div class="page two"></div>
<div class="page three"></div>
JSfiddle: https://jsfiddle.net/fw8h7v4q/

How to set up "stop" after setInterval() method?

i have image gallery ant i set up setinterval, now i want that it should be stopped after two or tree circle.
This is my html Code:
<div id="slider">
<img src="http://imgsrc.hubblesite.org/hu/gallery/db/spacecraft/24/formats/24_web.jpg">
<img src="http://imgsrc.hubblesite.org/hu/gallery/db/spacecraft/27/formats/27_web.jpg">
<img src="http://imgsrc.hubblesite.org/hu/gallery/db/spacecraft/32/formats/32_web.jpg">
<img src="http://imgsrc.hubblesite.org/hu/gallery/db/spacecraft/33/formats/33_web.jpg">
</div>
css:
#slider {
width: 400px;
height: 300px;
position: relative;
overflow: hidden
}
#slider img {
position: absolute;
top: 0;
left: 0;
opacity: 0;
transition: 0.25s
}
and Javascript:
var pics;
var current = 0; // first next() moves to pics[0], the first image
window.addEventListener("load", function() {
pics = document.querySelectorAll("#slider img");
});
setInterval(function() {
var nextImage = (current + 1) % pics.length;
pics[current].style.opacity = 0;
pics[nextImage].style.opacity = 1;
current = nextImage;
}, 3000);
Here's your answer: Stop setInterval call in JavaScript
Save the interval ID when you create it, keep track of the number of times your slides have rotated, and then cancel the interval.
Use a counter variable to track the number of cycles & clear the timer based on that limit value.
JS Code:
var counter = 0;
var limit = 3 ;
var timer;
timer =setInterval(function () {
if(counter === 3){
clearInterval(timer);
return;
}
counter++;
//do some stuff here after 1 second delay
},1000);
You could use setTimeout instead.
var pics;
var current = 0; // first next() moves to pics[0], the first image
var stop = 3; //define when you want to stop
window.addEventListener("load", function() {
pics = document.querySelectorAll("#slider img");
});
function switchImage()
{
var nextImage = (current + 1) % pics.length;
pics[current].style.opacity = 0;
pics[nextImage].style.opacity = 1;
current = nextImage;
stop--;
if(stop != 0)
setTimeout(switchImage,3000);
}
setTimeout(switchImage,3000);
You can do like this.
var refreshIntervalId = setInterval(function() {
var nextImage = (current + 1) % pics.length;
pics[current].style.opacity = 0;
pics[nextImage].style.opacity = 1;
current = nextImage;
}, 3000);
clearInterval(refreshIntervalId);

Why isn't it possible to change max-height with % in javascript?

I'm trying to build a responsive menu, with a hamburger icon. I want the menu list to slide in and out, no jquery - pure javascript only.
HTML :
<div id="animation">
</div>
<button id="toggle">Toggle</button>
CSS :
div {
width: 300px;
height: 300px;
background-color: blue;
}
Javascript :
var but = document.getElementById('toggle');
var div = document.getElementById('animation');
var animate = function(type, callback){
var inter = -1, start = 100, end = 0;
if(type==true){
inter = 1;
start = 0;
end = 100;
}
var si = setInterval(function(){
console.log('maxheight');
div.style.maxHeight = (start + inter) + '%';
if(start == end){
clearInterval(si);
}
}, 10);
}
var hidden = false;
but.onclick = function(){
animate(hidden, function(){
hidden = (hidden == false) ? true : false;
});
}
div.style.maxHeight = "50%";
The problem is that proportional height in an element needs a fixed height on the parent, and you didn't provided any parent with a fixed height because for the maxHeight property too the % Defines the maximum height in % of the parent element.
You have to put your div in a parent container with a fixed height, this is your working code:
var but = document.getElementById('toggle');
var div = document.getElementById('animation');
var animate = function(type, callback) {
var inter = -1,
start = 100,
end = 0;
if (type) {
inter = 1;
start = 0;
end = 100;
}
var si = setInterval(function() {
console.log('maxheight');
div.style.maxHeight = (start + inter) + '%';
if (start == end) {
clearInterval(si);
}
}, 10);
}
var hidden = false;
but.onclick = function() {
animate(hidden, function() {
hidden = !hidden ;
});
}
div.style.maxHeight = "50%";
#animation {
width: 300px;
height: 300px;
background-color: blue;
}
#parent {
width: 500px;
height: 500px;
}
<div id="parent">
<div id="animation">
</div>
<button id="toggle">Toggle</button>
</div>
Note:
As stated in comments there are some statements in your JavaScript code that need to be adjusted:
if(type==true) can be written as if(type).
hidden = (hidden == false) ? true : false; can be shortened to hidden = !hidden
There seems to be a few errors with your code. I have fixed the js and added comments to what I have changed
var but = document.getElementById('toggle');
var div = document.getElementById('animation');
var animate = function (type, callback) {
var start = 100,
end = 0;
if (type) {
start = 0;
end = 100;
}
var si = setInterval(function () {
if (type) { // check whether to open or close animation
start++;
} else {
start--
}
div.style.maxHeight = start + '%';
if (start == end) {
clearInterval(si);
}
}, 10);
callback.call(this); // do the callback function
}
var hidden = false;
but.onclick = function () {
animate(hidden, function () {
hidden = !hidden; // set hidden to opposite
});
}
/*make sure parent container has a height set or max height won't work*/
html, body {
height:100%;
margin:0;
padding:0;
}
div {
width: 300px;
height: 300px;
background-color: blue;
}
<div id="animation"></div>
<button id="toggle">Toggle</button>
Example Fiddle

Why doesn't this mouseover/rollover work?

I have 3 images (pic1, pic2, pic3) that on click of the div ID change to (pic4, pic5, pic6). All this works fine but I need to put in a mouseover command that when hovering over pic2, it changes to pic 7 and on mouseout it goes back to pic 2. I am unsure as to why this part of my code isn't working, is it a syntax error? The two functions I am trying to use to do this are "rolloverImage" and "init".
HTML
<div id="content1">
<img src="pic1.jpg" alt="pic1"/>
<img src="pic2.jpg" alt="pic2" id="pic2"/>
<img src="pic3.jpg" alt="pic3"/>
</div>
Javascript
var g = {};
//Change background colors every 20 seconds
function changebackground() {
var backColors = ["#6AAFF7", "#3AFC98", "#FC9B3A", "#FF3030", "#DEDEDE"];
var indexChange = 0;
setInterval(function() {
var selectedcolor = backColors[indexChange];
document.body.style.background = selectedcolor;
indexChange = (indexChange + 1) % backColors.length;
}, 20000);
}
function rolloverImage(){
if (g.imgCtr == 0){
g.pic2.src = g.img[++g.imgCtr];
}
else {
g.pic2.src = g.img[--g.imgCtr];
}
}
function init(){
g.img = ["pic2.jpg", "pic7.jpg"];
g.imgCtr = 0;
g.pic2 = document.getElementById('pic2');
g.pic2.onmouseover = rolloverImage;
g.pic2.onmouseout = rolloverImage;
}
window.onload = function() {
var picSets = [
["pic1.jpg", "pic2.jpg", "pic3.jpg"],
["pic4.jpg", "pic5.jpg", "pic6.jpg"],
];
var currentSetIdx = 0;
var contentDiv = document.getElementById("content1");
var images = contentDiv.querySelectorAll("img");
refreshPics();
contentDiv.addEventListener("click", function() {
currentSetIdx = (currentSetIdx + 1) % picSets.length;
refreshPics();
});
function refreshPics() {
var currentSet = picSets[currentSetIdx];
var i;
for(i = 0; i < currentSet.length; i++) {
images[i].src = currentSet[i];
}
}
changebackground();
init();
}

Categories