Make slider counter, count just the amount of slides in the slider - javascript

I made a jQuery slider for a website, it has 9 slides, and I want the counter to count JUST until 9. What happens is that as soon as I get to the last slide (09 of 09) and CLICK on the NEXT bnt, it goes to the first slide (01 of 09) and when I click to go to the second slide I get this: 11 of 09. Please help!
It's an infinite slider, and would like the counter to work "UP" and "DOWN", meaning to have the counter add if the user goes NEXT and subtract if the user goes previous.
The slider is in this site http://madebymorro.com/web_dev_vavilco/
at the very bottom.
Thanks!
the code I have is HTML:
<section id="construction">
<div class="wrapper">
<div id="home-slider">
<div id="slider-data">
<div class="count">
<span class="current">1</span>/09
</div>
<div class="slider-nav">
<div class="prev"><img src="images/home-prev.svg" alt=""></div>
<div class="next"><img src="images/home-next.svg" alt=""></div>
</div>
</div>
<div id="home-slider-c">
<section class="slider-project">
<img src="images/home-slider001.jpg" alt="">
<div class="img-data">
<p>zaragoza</p>
<p>apartamentos</p>
</div>
</section>
<section class="slider-project">
<img src="images/home-slider002.jpg" alt="">
<div class="img-data">
<p>bravtevilla</p>
<p>casas</p>
</div>
</section>
<section class="slider-project">
<img src="images/home-slider003.jpg" alt="">
<div class="img-data">
<p>business Center Dorado</p>
<p>oficinas</p>
</div>
</section>
<section class="slider-project">
<img src="images/home-slider004.jpg" alt="">
<div class="img-data">
<p>balcones de la trinidad</p>
<p>apartamentos</p>
</div>
</section>
<section class="slider-project">
<img src="images/home-slider005.jpg" alt="">
<div class="img-data">
<p>gratamira 131</p>
<p>apartamentos</p>
</div>
</section>
<section class="slider-project">
<img src="images/home-slider006.jpg" alt="">
<div class="img-data">
<p>torre olaya plaza</p>
<p>apartamentos y plaza comercial</p>
</div>
</section>
<section class="slider-project">
<img src="images/home-slider007.jpg" alt="">
<div class="img-data">
<p>torre olaya plaza</p>
<p>locales comerciales</p>
</div>
</section>
<section class="slider-project">
<img src="images/home-slider008.jpg" alt="">
<div class="img-data">
<p>plaza castilla</p>
<p>apartamentos</p>
</div>
</section>
<section class="slider-project">
<img src="images/home-slider009.jpg" alt="">
<div class="img-data">
<p>sauses del country</p>
<p>apartamentos</p>
</div>
</section>
</div>
</div>
</div>
the code I have is jQuery:
var slider = $('#home-slider-c'),
next = $('.slider-nav .next'),
prev = $('.slider-nav .prev');
$('#home-slider-c section:last-child').insertBefore('#home-slider-c section:first-child');
slider.css('margin-left', '-100%');
var n = 0;
function getNext() {
var e = n === $('.slider-project').length - 1 ? 0 : n + 1;
$(".current").html(e + 1);
n++;
console.log(e);
slider.animate({
marginLeft: '-200%'
}, 700, function() {
$('#home-slider-c section:first-child').insertAfter('#home-slider-c section:last-child');
slider.css('margin-left', '-100%');
});
// $(".current").html(e++);
}
var n = 0;
function getPrev() {
var e = n <= 0 ? $('.slider-project').length - 1 : n - 1;
$(".current").html(e + 1);
n--;
console.log(e);
slider.animate({
marginLeft: 0
}, 700, function() {
$('#home-slider-c section:last-child').insertBefore('#home-slider-c section:first-child');
slider.css('margin-left', '-100%');
});
}
next.on('click', getNext);
prev.on('click', getPrev);

Try using this single counter e initialized to 1
....
var e= 1;
function getNext() {
e= e<$('.slider-project').length?e:0;
e++;
$(".current").html(e);
// n++;
console.log(e);
....
}
function getPrev() {
e= e<=1?$('.slider-project').length+1:e;
e--;
$(".current").html(e);
// n--;
console.log(e);
....
}

Use the Reminder Operator % Here you go:
var tot = 6, // Let's say we have 6 slides.
c = 0; // Dummy counter
$("#prev, #next").on("click", function(){
// Increment or decrement counter depending on button ID
c = this.id==="next" ? ++c : --c;
// OK almost there, now let's loop our counter to prevent exceeding <0 or >5
// >5 since index 5 is the 6th slide (tot-1).
// If counter went less than 0 (prev button) than set it to tot-1
// For all other cases use modulo % which will reset it to 0 automagically.
c = c<0 ? tot-1 : c%tot;
$("#test").text(c);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id=prev>«</button>
<span id=test>0</span>
<button id=next>»</button>
The above can be written using a bigger if else logic, but if it's all clear than you can simply use this snippet and drop it into any current or future gallery you build:
// Logic to loop counter on prev / next click:
c = (this.id==="next" ? ++c : --c) < 0 ? tot-1 : c%tot;

Related

Javascript - Carousel managed automatically and with keyboard

I'm developing an automatic and keyboard managed carousel slider but it doesn't respond when I hit the previous or back buttons in the keyboard. It works when I click the previous and next buttons, and changes automatically.
Here is my HTML and Js code:
let currentSlide = 0;
const slides = document.querySelectorAll(".picture")
//carousel
const init = (n) => {
slides.forEach((picture, index) => {
picture.style.display = "none"
})
slides[n].style.display = "block"
}
//left and right buttons
document.addEventListener("DOMContentLoaded", init(currentSlide))
const next = () => {
currentSlide >= slides.length - 1 ? currentSlide = 0 : currentSlide++
init(currentSlide)
}
const prev = () => {
currentSlide <= 0 ? currentSlide = slides.length - 1 : currentSlide--
init(currentSlide)
}
document.querySelector(".buttonleft").addEventListener('click', prev)
document.querySelector(".buttonright").addEventListener('click', next)
//each 3 seconds change picture
setInterval(() => {
next()
}, 3000);
// NAVIGATE WITH KEYS
document.keydown(function(e) {
if (e.keyCode === 37) {
// Previous
$(".buttonleft").click();
return false;
}
if (e.keyCode === 39) {
// Next
$(".buttonright").click();
return false;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="carousel-container">
<!-- next and prev buttons -->
<div class="navigation">
<div class="btn buttonleft">
<img src="assets/img/left.png">
</div>
<div class="btn buttonright">
<img src="assets/img/right.png">
</div>
<!-- carousel -->
<div class="carousel">
<div class="logo">
<img src="assets/img/mmlogo.png" alt="Yahoo" class="image">
</div>
<div class="picture fade">
<a href="http://www.yahoo.com" target="_blank">
<img src="assets/img/image1.png" alt="Cloudy with a Chance of Meatballs" class="image">
</a>
</div>
<div class="picture fade">
<a href="http://www.google.com" target="_blank">
<img src="assets/img/image2.png" alt="Cloudy with a Chance of Meatballs" class="image">
</a>
</div>
<div class="picture fade">
<a href="http://www.youtube.com" target="_blank">
<img src="assets/img/image3.png" alt="Cloudy with a Chance of Meatballs" class="image">
</a>
</div>
<div class="picture fade">
<a href="http://www.gmail.com" target="_blank">
<img src="assets/img/image4.png" alt="Cloudy with a Chance of Meatballs" class="image">
</a>
</div>
<div class="picture fade">
<a href="http://www.outlook.com" target="_blank">
<img src="assets/img/image5.png" alt="Cloudy with a Chance of Meatballs" class="image">
</a>
</div>
</div>
</div>
</div>
Any ideas? I don't want to use Bootstrap.
Thanks!
Looks like you're using vanilla javascript, until the last event listener. Looks like jquery.
Make it vanilla js like you did above. It works fine.
Keeping your console tools open will give you a good idea of what's wrong.
document.addEventListener('keydown', (function(e) {
if (e.keyCode === 37) {
// Previous
console.log("prev");
}
if (e.keyCode === 39) {
// Next
console.log("next");
}
}));

Show active class

I want to add class 'active' to next div 1 second before first is removed.
Practically, I want to have an 'active' class on 2 elements at the same time for that 1 second.
Can someone help me?
Thanks
<div class="map-inner">
<div class="map-location-outer">
<div class="map-location-inner location1 active">
<div class="map-location">
<div class="map-icon">
<img src="i/content/map-icon2.svg">
</div>
<span class="map-pin"><span></span></span>
</div><!-- map-location -->
</div>
</div>
<div class="map-location-outer">
<div class="map-location-inner location2">
<div class="map-location">
<div class="map-icon">
<img src="i/content/map-icon3.svg">
</div>
<span class="map-pin"><span></span></span>
</div><!-- map-location -->
</div>
</div>
<div class="map-location-outer">
<div class="map-location-inner location3">
<div class="map-location">
<div class="map-icon">
<img src="i/content/map-icon1.png">
</div>
<span class="map-pin"><span></span></span>
</div><!-- map-location -->
</div>
</div>
</div>
var x = 1;
function updateClass() {
let a = $(".map-location-inner.active");
a.removeClass("active");
a = a.parent().next(".map-location-outer");
if (a.length == 0)
a = $(".map-location-outer").first();
a.find(".map-location-inner").addClass("active");
}
setInterval(function () {
updateClass();
}, x * 5500);
You can use setTimeout to wait before removing 1st .active class and add 2nd .active class before removing 1st one.
var x = 1;
function updateClass() {
let a = $(".map-location-inner.active");
let b = a.parent().next(".map-location-outer");
if (b.length == 0)
b = $(".map-location-outer").first();
b.find(".map-location-inner").addClass("active");
setTimeout(function() {
a.removeClass("active");
}, 1000);
}
setInterval(function () {
updateClass();
}, x * 5500);

How can I reset my html image gallery to start with first image after leaving it?

I have a website with multiple image galleries on different parts of the website. When you click on the image of specific gallery it changes to next one of that gallery and so on.
What I am trying to achieve is to reset the previous gallery to image 1 when you start clicking on a different gallery. So when the user goes back to the previous gallery, it would start from the first image.
Code used for the galleries:
let projectIndexes = {
project1: 1,
project2: 1,
}
showDivs("project1", projectIndexes.project1);
showDivs("project2", projectIndexes.project2);
function plusDivs(project, n) {
showDivs(project, projectIndexes[project] += n);
}
function showDivs(project, index) {
let i;
let x = document.getElementById(project).getElementsByClassName("slidess");
if (index > x.length) { index = 1 }
if (index < 1) { index = x.length }
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[index - 1].style.display = "block";
projectIndexes[project] = index;
let elements = document.getElementById(project).querySelector('.imgslide').children;
let imgNames = [];
for (let i = 0; i < elements.length; i++) {
imgNames.push(elements[i].children[0].children[0].alt);
}
}
<div class="slide">
<div class="slide-content">
<div class="nextt" onclick="plusDivs('project1', 1)"></div>
</div>
<div class="image-container container prjct">
<div class="projects" id="project1">
<div class="imgslide noselect">
<div class="content-container slidess">
<div class="style-3 style-3-left">
<img class="imageName" alt="Img" src="">
</div>
<div class="style-3 style-3-middle">
<img class="imageName" alt="Img" src="">
</div>
<div class="style-3 style-3-right">
<img class="imageName" alt="Img" src="">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="slide">
<div class="slide-content">
<div class="nextt" onclick="plusDivs('project2', 1)"></div>
</div>
<div class="image-container container prjct">
<div class="projects" id="project2">
<div class="imgslide noselect">
<div class="content-container slidess">
<div class="style-3 style-3-left">
<img class="imageName" alt="Img" src="">
</div>
<div class="style-3 style-3-middle">
<img class="imageName" alt="Img" src="">
</div>
<div class="style-3 style-3-right">
<img class="imageName" alt="Img" src="">
</div>
</div>
<!-- <div class="img-name"></div> -->
</div>
</div>
</div>
</div>
I know a way to force show the first element, but it turns out it does that for all projects.
What I was not able to find is a way to recognise when clicking on a new project, that the previous and only previous project needs to reset to first image.
I have been struggling with this for a while now and cannot make it work, so any help would be highly appreciated. And if something is not clear, let me know and I will clarify things.
If I'm following you correctly, the following should do it.
function resetPriorGalleries(currentProject) {
var projectDivs = document.getElementsByClassName("projects");
for (let i = 0; i < projectDivs.length; i++) {
if (projectDivs[i].id === currentProject)
return;
showDivs(projectDivs[1].id, 1);
}
}
The best place to call it would probably be in the onclicks.
onclick="plusDivs('project2', 1); resetPriorGalleries('project2');"

Automate a slider with pause and resume functions

I have a slider and I would like to automate it with pause and resume functions. I found this great snippet of code that allows me to pause and resume, however, it only allows me to pause once.
I am struggling to figure out how to make it so the user can pause as many times as they like.
here is the complete code:
$s = 1000; // slide transition speed (for sliding carousel)
$d = 5000; // duration per slide
$w = $('.slide').width(); // slide width
function IntervalTimer(callback, interval) {
var timerId, startTime, remaining = 0;
var state = 0; // 0 = idle, 1 = running, 2 = paused, 3= resumed
this.pause = function () {
if (state != 1) return;
remaining = interval - (new Date() - startTime);
window.clearInterval(timerId);
state = 2;
$('.timer').stop(true, false)
};
this.resume = function () {
if (state != 2) return;
state = 3;
window.setTimeout(this.timeoutCallback, remaining);
$('.timer').animate({"width":$w}, remaining);
$('.timer').animate({"width":0}, 0);
};
this.timeoutCallback = function () {
if (state != 3) return;
callback();
startTime = new Date();
timerId = window.setInterval(callback, interval);
state = 1;
};
startTime = new Date();
timerId = window.setInterval(callback, interval);
state = 1;
}
var starttimer = new IntervalTimer(function () {
autoSlider()
}, $d);
timer();
$('.slider-content').hover(function(ev){
starttimer.pause()
}, function(ev){
starttimer.resume()
});
function timer() {
$('.timer').animate({"width":$w}, $d);
$('.timer').animate({"width":0}, 0);
}
Any help is greatly appreciated.
UPDATE:
Here is the HTML
<div class="slider-content">
<div class="timer"></div>
<div class="slide 1">
<div class="hero-container">
<div class="header-content-container">
<h1 class="entry-title"></h1>
<hr>
<div class="flex-container">
<div class="col1"></div>
<div class="col2"></div>
</div>
<div class="post-link"></div>
</div>
</div>
</div>
<div class="slide 2">
<div class="hero-container">
<div class="header-content-container">
<h1 class="entry-title"></h1>
<hr>
<div class="flex-container">
<div class="col1"></div>
<div class="col2"></div>
</div>
<div class="post-link"></div>
</div>
</div>
</div>
<div class="slide 3">
<div class="hero-container">
<div class="header-content-container">
<h1 class="entry-title"></h1>
<hr>
<div class="flex-container">
<div class="col1"></div>
<div class="col2"></div>
</div>
<div class="post-link"></div>
</div>
</div>
</div>
<div class="slide 4">
<div class="hero-container">
<div class="header-content-container">
<h1 class="entry-title"></h1>
<hr>
<div class="flex-container">
<div class="col1"></div>
<div class="col2"></div>
</div>
<div class="post-link"></div>
</div>
</div>
</div>
</div>

iterating through childs of div with class insides :nth-child in jQuery

i am trying to iterate through the children of the div with class insides.
so far it has been a failure.
here is the html:
<div class="insides">
<div class="pen" style="background-image:url('images/video.png');background-size:cover">
<div class="cover"></div>
<div class="items">
<div class="title">
fullscreen-centered-blurred-video-background
</div>
<div class="desc">
Quick video covers fullscreen with blur effect and grayscale (looping) with working input fields
</div>
<a class="button button-secondary button-small" href="http://codepen.io/peterbs/pen/QpyrMb">
View On CodePen
</a>
</div>
</div>
<div class="pen" style="background-image:url('images/form.png');background-size:cover">
<div class="cover"></div>
<div class="items">
<div class="title">
Loading-form
</div>
<div class="desc">
Simple and fast loading form that is displayed after loading is finished
</div>
<a class="button button-secondary button-small" href="http://codepen.io/peterbs/pen/PpZExY">
View On CodePen
</a>
</div>
</div>
<div class="pen" style="background-image:url('images/horizontal.png');background-size:cover">
<div class="cover"></div>
<div class="items">
<div class="title">
align-vertically
</div>
<div class="desc">
Very easy javascript that aligns children vertically within its parents because css had weak support.
</div>
<a class="button button-secondary button-small" href="http://codepen.io/peterbs/pen/aJNEvB">
View On CodePen
</a>
</div>
</div>
<div class="pen" style="background-image:url('images/navbar.png');background-size:cover">
<div class="cover"></div>
<div class="items">
<div class="title">
navbar-animations
</div>
<div class="desc">
navigation bar with 3 different animations. One more will be coming soon.
</div>
<a class="button button-secondary button-small" href="http://codepen.io/peterbs/pen/dvMpyV">
View On CodePen
</a>
</div>
</div>
</div>
.pen has opacity: 0
and when the user scrolls down a little bit i want them to show 1 by 1.
here is the javascript:
$(document).ready(function(){
window.addEventListener('scroll',function(){
var scroll = $(this).scrollTop();
$('.content').css('transform', 'translateY( '+ scroll / 2 +'px )' );
if(scroll > 120){
for(x = 0; x <= 4 ; x++){
setTimeout(function(){
$('.insides:nth-child('+ x +')').css('opacity','1');
}, 700*x);
}
}else{
for(x = 0; x <= 4 ; x++){
setTimeout(function(){
$('.insides:nth-child('+ x +')').css('opacity','0');
}, 700*x);
}
}
});
var scroll = $(this).scrollTop();
if(scroll > 120){
for(x = 0; x <= 4 ; x++){
setTimeout(function(){
$('.insides:nth-child('+ x +')').css('opacity','1');
}, 700*x);
}
}else{
for(x = 0; x <= 4 ; x++){
setTimeout(function(){
$('.insides:nth-child('+ x +')').css('opacity','0');
}, 700*x);
}
}
});
i honestly have no idea why it is not working. it just doesn't show
here is a jsfiddle: https://jsfiddle.net/f176ch6r/
it doesn't look perfect in the fiddle but it does the job
Two problems here:
the nth-child selector must be applied on your .pen elements
because of the setTimeout all your $('.insides:nth-child('+ x +')') selectors will have the same x
here is what I would write:
window.addEventListener('scroll', _onScroll);
_onScroll();
function _onScroll(){
var x,
scroll = $(this).scrollTop(),
show = scroll > 120;
$('.content').css('transform', 'translateY( '+ scroll / 2 +'px )' );
for(x = 0; x <= 4 ; x++){
_toggle(x, show);
}
}
function _toggle(index, bShow){
setTimeout(function(){
$('.insides .pen:nth-child('+ (index + 1) +')').css('opacity', bShow ? 1 : 0);
}, 700*index);
}
I also updated your jsfiddle

Categories