I'm trying to write my first text slider in JS, which seemed super easy at first, but it bevahes very stange.
When the 'previous' button is clicked it works fine but ommits the last <li> item, when the 'next' button is clicked all of the <li>s become an empty class="" and that's all, it's doesn't slide to the next item.
Here's my code:
const slider = document.querySelector('.text-slider');
const sliderItems = slider.querySelectorAll('li');
const sliderNav = slider.querySelector('.slider-nav');
function changeSlide(e) {
// if the next button is clicked the direction is true
// if the prev button is clicked the direction is false
const direction = e.target.classList.contains('nav-next') ? true : false;
const itemsInTotal = sliderItems.length;
for(let i = 0; i < itemsInTotal; i++) {
// if the item is active
if(sliderItems[i].classList.contains('active')) {
//delete the active class
sliderItems[i].classList.remove('active');
//if the NEXT button was clicked
if(direction) {
//if it's the last slide
if(i === itemsInTotal-1) {
sliderItems[0].classList.add('active');
}
else {
sliderItems[i+1].classList.add('active');
}
// if the PREV button was clicked
} else {
//if it's the first element
if(i === 0) {
sliderItems[itemsInTotal-1].classList.add('active');
} else {
sliderItems[i-1].classList.add('active');
}
}
}
};
}
sliderNav.addEventListener('click', changeSlide);
.hero {
background-color: #252525;
min-height: 100vh;
position: relative;
}
.hero ul {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center; }
.hero ul li {
display: none;
color: #fff;
text-align: center;
font-family: "Frank Ruhl Libre", serif;
font-size: 2em; }
.hero ul li span {
color: #f5989d;
text-transform: uppercase;
font-family: "Josefin Sans", sans-serif;
font-size: 1.3em;
font-weight: 700;
display: block; }
.hero ul li.active {
display: block; }
.hero .slider-nav a {
border:1px solid red;
position: absolute;
content: ' ';
width: 30px;
height: 30px;
background: url("img/arrow-r.png");
background-size: contain;
position: absolute;
top: calc( 50% - 15px );
z-index: 10; }
.hero .slider-nav a:hover {
cursor: pointer; }
.hero .slider-nav a.nav-prev {
transform: rotate(180deg);
left: 7%; }
.hero .slider-nav a.nav-next {
right: 7%; }
<section class="hero">
<div class="text-slider">
<div class="slider-nav">
<a class="slider-nav nav-prev"></a>
<a class="slider-nav nav-next"></a>
</div>
<ul>
<li class="active">I like take photos <span>in the woods</span></li>
<li>I like observing <span>people and their emotions</span></li>
<li>I always take <span>the best of life</span></li>
<li>I always take <span>the best of life 2</span></li>
<li>I always take <span>the best of life 3</span></li>
</ul>
</div>
</section>
I will appreciate any help.
const slider = document.querySelector('.text-slider');
const sliderItems = slider.querySelectorAll('li');
const sliderNav = slider.querySelector('.slider-nav');
let counter = 0;
function changeSlide(e) {
// if the next button is clicked the direction is true
// if the prev button is clicked the direction is false
const direction = e.target.classList.contains('nav-next') ? true : false;
const itemsInTotal = sliderItems.length;
for(let i = 0; i < itemsInTotal; i++) {
// if the item is active
if(sliderItems[i].classList.contains('active')) {
//delete the active class
sliderItems[i].classList.remove('active');
//if the NEXT button was clicked
if(direction) {
//if it's the last slide
if(i === itemsInTotal-1) {
sliderItems[0].classList.add('active');
}
else {
sliderItems[i+1].classList.add('active');
break;
}
// if the PREV button was clicked
} else {
//if it's the first element
if(i === 0) {
sliderItems[itemsInTotal-1].classList.add('active');
break;
} else {
sliderItems[i-1].classList.add('active');
}
}
}
};
}
sliderNav.addEventListener('click', changeSlide);
.hero {
background-color: #252525;
min-height: 100vh;
position: relative;
}
.hero ul {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center; }
.hero ul li {
display: none;
color: #fff;
text-align: center;
font-family: "Frank Ruhl Libre", serif;
font-size: 2em; }
.hero ul li span {
color: #f5989d;
text-transform: uppercase;
font-family: "Josefin Sans", sans-serif;
font-size: 1.3em;
font-weight: 700;
display: block; }
.hero ul li.active {
display: block; }
.hero .slider-nav a {
border:1px solid red;
position: absolute;
content: ' ';
width: 30px;
height: 30px;
background: url("img/arrow-r.png");
background-size: contain;
position: absolute;
top: calc( 50% - 15px );
z-index: 10; }
.hero .slider-nav a:hover {
cursor: pointer; }
.hero .slider-nav a.nav-prev {
transform: rotate(180deg);
left: 7%; }
.hero .slider-nav a.nav-next {
right: 7%; }
<section class="hero">
<div class="text-slider">
<div class="slider-nav">
<a class="slider-nav nav-prev"></a>
<a class="slider-nav nav-next"></a>
</div>
<ul>
<li class="active">I like take photos <span>in the woods</span></li>
<li>I like observing <span>people and their emotions</span></li>
<li>I always take <span>the best of life</span></li>
<li>I always take <span>the best of life 2</span></li>
<li>I always take <span>the best of life 3</span></li>
</ul>
</div>
</section>
Okay, I added 2 break in the loop to stop the iteration after applying the class on the next element.
In fact, you have a problem with your previous button too because the state "Best of life 3" is never displayed.
I propose you to use a while loop instead a for, because you change always all "li" instead of changing only the concerned 2 (old active and new active).
I think, this will work :
changeSlide(e: any) {
// if the next button is clicked the direction is true
// if the prev button is clicked the direction is false
const direction = e.target.classList.contains('nav-next') ? true : false;
const itemsInTotal = this.sliderItems.length;
let isChangeDone = false;
let i = 0;
while(!isChangeDone && i < itemsInTotal) {
// if the item is active
if(this.sliderItems[i].classList.contains('active')) {
//delete the active class
this.sliderItems[i].classList.remove('active');
//if the NEXT button was clicked
if(direction) {
//if it's the last slide
if(i === itemsInTotal-1) {
this.sliderItems[0].classList.add('active');
isChangeDone = true;
}
else {
this.sliderItems[i+1].classList.add('active');
isChangeDone = true;
}
// if the PREV button was clicked
} else {
//if it's the first element
if(i === 0) {
this.sliderItems[itemsInTotal-1].classList.add('active');
isChangeDone = true;
} else {
this.sliderItems[i-1].classList.add('active');
isChangeDone = true;
}
}
}
i++;
};
}
Let me know.
Related
I created a simple carousel using HTML, CSS, and Javascript.
Clicking the left button shows the previous slide and the right one shows the next slide.
But my concern is that slide change is not working correctly
when clicking the next button: After the final slide, it won't go to the first slide again.
when clicking the previous button: After the first slide, it won't go again to last the slide again.
So please review my code and let me know my error.
let right = document.querySelector('.nxt');
let left = document.querySelector('.pre');
let slids = document.querySelector('.slids');
let first = document.querySelector('.first');
let scond = document.querySelector('.scond');
let third = document.querySelector('.third');
let fouth = document.querySelector('.fouth');
let slidesArray=[first,scond,third,fouth];
let index= 0;
let activeSlide= slidesArray[index].classList.add('active');
left.addEventListener('click',()=>{
if (++index > 0) {
slidesArray[index].classList.add('active');
}
});
right.addEventListener('click',()=>{
if (index > 0) {
slidesArray[index].classList.add('deactive');
slidesArray[--index].classList.add('active');
}
});
body{
display: flex;
justify-content: center;
align-items: center;
}
.slids>*{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50% ,-50%);
width: 400px;
height: 350px;
font-size: 50px;
font-weight: 600;
display: grid;
place-items: center;
border-radius: 20px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
visibility: hidden;
}
.active{
visibility: visible;
}
.first{
background-color: #F7EC09;
}
.scond{
background-color: #3EC70B;
}
.third{
background-color: #3B44F6;
}
.fouth{
background-color: #A149FA;
}
.btn{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50% ,-50%);
display: flex;
gap: 450px;
}
.nxt, .pre{
font-size: 100px;
font-weight: 700;
background: none;
border: none;
cursor: pointer;
}
<body>
<div class="slids">
<div class="first">1</div>
<div class="scond">2</div>
<div class="third">3</div>
<div class="fouth">4</div>
</div>
<div class="btn">
<button class="nxt"><</button>
<button class="pre">></button>
</div>
A chained ternary expression can be used to determine the new index number in a single line:
to = to >= size ? 0 : to < 0 ? size - 1 : to;
Details are commented in example
// Reference the buttons
let next = document.querySelector('.next');
let prev = document.querySelector('.prev');
/*
Collect all div.slide into an array
Define the array's size
Define a number value outside of the function
*/
let slides = [...document.querySelectorAll('.slide')];
let size = slides.length;
let index = 0;
// Bind click event to button.prev
prev.onclick = event => move(index - 1);
// Bind click event to button.next
next.onclick = event => move(index + 1);
/*
Pass newest index number
Ternary expression:
If the given number is greater than or equal to size of the array...
...return 0...
...If the given number is less than 0...
...return last index of array...
...otherwise return the given number
Toggle the current .slide.active and new .slide
Assign index as the given number
*/
function move(to) {
to = to >= size ? 0 : to < 0 ? size - 1 : to;
slides[index].classList.toggle("active");
slides[to].classList.toggle("active");
index = to;
}
html {
font: 300 3vmin/1 Consolas;
}
body {
display: flex;
justify-content: center;
align-items: center;
}
main {
display: flex;
justify-content: center;
align-items: center;
position: relative;
max-width: max-content;
min-height: 100vh;
}
.slides {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: 420px;
height: 400px;
overflow: hidden;
}
.slide {
display: grid;
place-items: center;
position: absolute;
top: 50%;
left: 50%;
width: 400px;
height: 350px;
border-radius: 20px;
font-size: 50px;
font-weight: 600;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
visibility: hidden;
transform: translate(-50%, -50%);
}
.active {
visibility: visible;
}
.slide:first-of-type {
background-color: #F7EC09;
}
.slide:nth-of-type(2) {
background-color: #3EC70B;
}
.slide:nth-of-type(3) {
background-color: #3B44F6;
}
.slide:nth-of-type(4) {
background-color: #A149FA;
}
.ctrl {
display: flex;
justify-content: space-between;
position: absolute;
top: 45%;
left: 45%;
width: 150%;
transform: translate(-50%, -50%);
}
.next,
.prev {
border: none;
font-size: 100px;
font-weight: 700;
background: none;
cursor: pointer;
}
<main>
<section class="slides">
<div class="slide active">1</div>
<div class="slide">2</div>
<div class="slide">3</div>
<div class="slide">4</div>
</section>
<menu class="ctrl">
<button class="prev"><</button>
<button class="next">></button>
</menu>
</main>
You need to reset the index of the slide when you click next and reach to maximum slide you need to reset index to 0 to return to first slide, also when you click prev and you in the first slide, you need to reset index to 3 to return the last slide.
let right = document.querySelector(".nxt");
let left = document.querySelector(".pre");
let slids = document.querySelector(".slids");
let first = document.querySelector(".first");
let scond = document.querySelector(".scond");
let third = document.querySelector(".third");
let fouth = document.querySelector(".fouth");
const elementsArr = [first, scond, third, fouth];
let slidesArray = [first, scond, third, fouth];
let index = 0;
let activeSlide = slidesArray[index].classList.add("active");
left.addEventListener("click", () => {
if (index === 3) {
index = -1;
}
index++;
resetActiveElements()
});
right.addEventListener("click", () => {
if (index === 0) index = 4;
index--;
resetActiveElements()
});
const resetActiveElements = () => {
elementsArr.forEach((element, i) => {
if (index === i) {
element.classList.add("active");
} else {
element.classList.remove("active");
}
});
}
body{
display: flex;
justify-content: center;
align-items: center;
}
.slids>*{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50% ,-50%);
width: 400px;
height: 350px;
font-size: 50px;
font-weight: 600;
display: grid;
place-items: center;
border-radius: 20px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
visibility: hidden;
}
.active{
visibility: visible;
}
.first{
background-color: #F7EC09;
}
.scond{
background-color: #3EC70B;
}
.third{
background-color: #3B44F6;
}
.fouth{
background-color: #A149FA;
}
.btn{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50% ,-50%);
display: flex;
gap: 450px;
}
.nxt, .pre{
font-size: 100px;
font-weight: 700;
background: none;
border: none;
cursor: pointer;
}
<body>
<div class="slids">
<div class="first">1</div>
<div class="scond">2</div>
<div class="third">3</div>
<div class="fouth">4</div>
</div>
<div class="btn">
<button class="nxt"><</button>
<button class="pre">></button>
</div>
/* <div class="btn">
<button class="pre"><</button>
<button class="nxt">></button>
</div> */
let right = document.querySelector('.nxt');
let left = document.querySelector('.pre');
let slids = document.querySelector('.slids');
let first = document.querySelector('.first');
let scond = document.querySelector('.scond');
let third = document.querySelector('.third');
let fouth = document.querySelector('.fouth');
let slidesArray = [first, scond, third, fouth];
let index = 0;
let activeSlide = slidesArray[index].classList.add('active');
left.addEventListener('click', () => {
slidesArray[index].classList.remove('active');
if (index == 0) {
index = 3;
slidesArray[index].classList.add('active');
} else {
index--;
slidesArray[index].classList.add('active');
}
});
right.addEventListener('click', () => {
slidesArray[index].classList.remove('active');
if (index == 3) {
index = 0;
slidesArray[index].classList.add('active');
} else {
index++;
slidesArray[index].classList.add('active');
}
});
I have a mobile menu that includes four list items. When you click on the "Features" list item, another unordered list is supposed to populate below it, and when you click it again, it's supposed to close it.
Here's my issue:
Inside the addEventListener function, I am calling two other functions (displayType and displayTypeCheck) inside the if, and else statement. When I do this and click on the "Features" list item, it opens but does not close when I click it again.
If I don't use the displayType and displayTypeCheck functions in the if and else statement and click on the "Features" list item, the UL will both open and close.
Why does the if and else statement that calls the other two functions not work, and how do I get it to work?
In the provided Javascript code below, the if and else statement that's commented out works, and the block that's not commented out is the code that doesn't entirely work.
const menuIcon = document.querySelector(".mobile-menu-icon");
const mobileMenu = document.querySelector(".mobile-menu");
const closeMenuIcon = document.querySelector(".close-menu-icon");
const featuresMobile = document.querySelector(".features-mobile");
const featuresMobileDropdown = document.querySelector(".features-mobile-dropdown");
const overlay = document.querySelector(".overlay");
function displayType(element, displayValue) {
element.style.display = displayValue;
}
function displayTypeCheck(element, displayValue) {
element.style.display === displayValue;
}
menuIcon.addEventListener("click", function () {
displayType(mobileMenu, 'block');
displayType(overlay, 'block');
});
closeMenuIcon.addEventListener("click", function () {
displayType(mobileMenu, 'none');
displayType(overlay, 'none');
});
featuresMobile.addEventListener("click", function () {
// if (featuresMobileDropdown.style.display === "block") {
// featuresMobileDropdown.style.display = "none";
// } else {
// featuresMobileDropdown.style.display = "block";
// }
if (displayTypeCheck(featuresMobileDropdown, "block")) {
displayType(featuresMobileDropdown, "none");
} else {
displayType(featuresMobileDropdown, "block");
}
});
#import url("https://fonts.googleapis.com/css2?family=Epilogue:wght#500;700&display=swap");
:root {
--almostWhite: hsl(0, 0%, 98%);
--mediumGray: hsl(0, 0%, 41%);
--almostBlack: hsl(0, 0%, 8%);
--navDropDownColor: #e9ecef;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
body {
min-height: 100vh;
font-family: "Epilogue", sans-serif;
background-color: var(--almostWhite);
}
header {
padding: .9375rem 2.5rem .9375rem 2.5rem;
max-width: 100rem;
margin: auto;
}
header nav {
display: flex;
align-items: center;
justify-content: flex-end;
}
header nav ul li {
cursor: pointer;
}
.register {
border: .125rem solid var(--mediumGray);
padding: .625rem .9375rem;
border-radius: .8125rem;
}
.mobile-menu-icon {
height: 3.125rem;
}
.mobile-menu-icon {
display: block;
cursor: pointer;
}
.mobile-menu .mobile-nav-links {
margin-top: 4.375em;
padding-left: .9375em;
color: var(--mediumGray);
}
.mobile-menu ul li {
padding: .625em;
}
.mobile-menu .mobile-nav-links li ul {
margin-left: .625em;
margin-top: .625em;
display: none;
}
.mobile-menu {
background-color: white;
width: 18.75em;
height: 100vh;
position: absolute;
top: 0;
right: 0;
z-index: 2;
display: none;
}
.close-menu-icon {
margin-left: auto;
margin-right: 1.25em;
margin-top: 1.25em;
display: block;
cursor: pointer;
height: 3.125em;
}
.login-register-mobile-container {
color: var(--mediumGray);
width: 90%;
margin: 3.125em auto;
}
.login-register-mobile-container span {
display: block;
text-align: center;
cursor: pointer;
}
.login-register-mobile-container span:first-child {
margin-bottom: 1.25em;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(.1875rem);
z-index: 1;
display: none;
}
<header>
<nav>
<img class="mobile-menu-icon" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Hamburger_icon.svg/2048px-Hamburger_icon.svg.png" alt="" />
<div class="mobile-menu">
<img
class="close-menu-icon"
src="https://cdn4.iconfinder.com/data/icons/user-interface-131/32/close-512.png"
alt=""
/>
<ul class="mobile-nav-links">
<li class="features-mobile">Features
<ul class="features-mobile-dropdown">
<li>Todo List</li>
<li>Calenders</li>
<li>Reminders</li>
<li>Planning</li>
</ul>
</li>
<li class="company-mobile">Company</li>
<li>Careers</li>
<li>About</li>
</ul>
<div class="login-register-mobile-container">
<span class="login">Login</span>
<span class="register">Register</span>
</div>
</div>
</nav>
<div class="overlay"></div>
</header>
You forgot the return statement.
function displayTypeCheck(element, displayValue) {
return element.style.display === displayValue;
}
Otherwise the function will always return undefined which is a falsey value.
Within the displayTypeCheck function, you aren't returning the boolean result of the conditions.
Without the return statement, it is returning void
function displayTypeCheck(element, displayValue) {
return element.style.display === displayValue;
}
I've made a simple slider that responses the mouseenter event.
The algorithm is when if the user moves its mouse pointer one of Appear menu contents, a div called .slate goes down.
My problem is in Chrome or Opera, when the user zoomed up by using CTRL + Mouse Wheel Up, the .slate is going to spills a bit and goes back up smoothly while Firefox doesn't:
I'm looking for a solution to remove this unwanted re-positioning except not using transition.
I've tried to give the transition more dynamically to resolve the problem. Add the transition when mouse entered to the Appear, remove it when mouse entered to Disappear.
But this one didn't work with an another new issue. The transition is going to ignore when I wag the mouse like this:
Are there any ways to resolve this problem?
CodePen: Original Code / Attempt 2
Snippet (Original):
'use strict';
class Slate {
constructor(header) {
this.header = document.querySelector(header);
this.slate = document.querySelector('.slate');
this.menu = this.header.querySelector('.menu');
this.contents = this.menu.querySelectorAll('.contents');
this.addEvent();
}
addEvent() {
this.contents.forEach((cur, idx) => {
cur.addEventListener('mouseenter', (e) => this.expand(e, idx));
})
}
expand(e, index) {
let lesser = (index < 2),
ternary = {
toggle: (lesser) ? this.slate.classList.add('toggle') : this.slate.classList.remove('toggle')
};
}
}
const proSlate = new Slate('header');
* {
margin: 0;
padding: 0;
font-family: Helvetica;
}
div, section, header {
position: relative;
}
ul, li {
list-style-type: none;
}
header, .slate {
width: 800px;
}
header {
height: 100px;
line-height: 100px;
background-color: rgba(69, 255, 0, .4);
}
.slate {
height: 400px;
line-height: 400px;
text-align: center;
color: white;
background-color: steelblue;
top: -25rem;
transition: top 500ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
z-index: -1;
font-size: 4rem;
}
.menu {
width: 100%;
display: flex;
}
.contents {
margin: 0 20px;
}
.toggle {
top: 0;
}
<header>
<ul class="menu">
<li class="contents">Appear</li>
<li class="contents">Appear</li>
<li class="contents">Disapper</li>
<li class="contents">Disapper</li>
</ul>
</header>
<div class="slate">
CONTEXT OF SLATE
</div>
Instead of using top, go for transform
'use strict';
class Slate {
constructor(header) {
this.header = document.querySelector(header);
this.slate = document.querySelector('.slate');
this.menu = this.header.querySelector('.menu');
this.contents = this.menu.querySelectorAll('.contents');
this.addEvent();
}
addEvent() {
this.contents.forEach((cur, idx) => {
cur.addEventListener('mouseenter', (e) => this.expand(e, idx));
})
}
expand(e, index) {
let lesser = (index < 2),
ternary = {
toggle: (lesser) ? this.slate.classList.add('toggle') : this.slate.classList.remove('toggle')
};
}
}
const proSlate = new Slate('header');
* {
margin: 0;
padding: 0;
font-family: Helvetica;
}
div,
section,
header {
position: relative;
}
ul,
li {
list-style-type: none;
}
header,
.slate {
width: 800px;
}
header {
height: 100px;
line-height: 100px;
background-color: rgba(69, 255, 0, .4);
}
.slate {
height: 400px;
line-height: 400px;
text-align: center;
color: white;
background-color: steelblue;
transform: translateY(-100%);
transition: transform 500ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
z-index: -1;
font-size: 4rem;
}
.menu {
width: 100%;
display: flex;
}
.contents {
margin: 0 20px;
}
.toggle {
transform: translateY(0);
}
<header>
<ul class="menu">
<li class="contents">Appear</li>
<li class="contents">Appear</li>
<li class="contents">Disapper</li>
<li class="contents">Disapper</li>
</ul>
</header>
<div class="slate">
CONTEXT OF SLATE
</div>
I'm creating a slider in Vanilla JavaScript.
I have a basic foundation.
Right now I'm not sure how to hide all of the other slides, and display only the current one. Then on the next/prev, show show the next slide, and hide the one that was before.
I have tried few things, but neither did work.
Here is the codepen: https://codepen.io/Aurelian/pen/LBGWpd?editors=0010
// Problem: Make the slides slide one after another
// and make the buttons work prev and next to bring prev or next slide
// Solution
// Select all slides
// On next/prev, get the left/right animate from 0 to 100 or from 0 to -100%
// On button press, get the prev/next parent node
// Add active class on the shown
// Solution Part 2
// Select all slides
// Get the length of the slides
// Display none on every slideItem
// Get the current slide
// Display block/flex on current slide
// On next, advance the slider index by 1
// On prev, advance the slider index by -1
// Make the slider slide every 3sec with setInterval
// Even listener on slider mousehover, stop the autoslide and add "PAUSED" HTML - add
// On live the slder, unpause and remove the HTML "PAUSED"
document.addEventListener('DOMContentLoaded', function() {
var slider = document.querySelector(".slider"),
sliderList = document.querySelector(".slider__list"),
sliderItems = document.querySelectorAll(".slider__item"),
sliderBtnPrev = document.querySelector(".slider__buttons--prev"),
sliderBtnNext = document.querySelector(".slider__buttons--next"),
sliderItemsLength = sliderItems.length,
currentIndex = 0,
isPaused = false;
function prevSlide() {
sliderItems[currentIndex].classList.remove('is-active');
currentIndex = (currentIndex + sliderItemsLength - 1) % sliderItemsLength;
sliderItems[currentIndex].classList.add('is-active');
}
function nextSlide() {
sliderItems[currentIndex].classList.remove('is-active');
currentIndex = (currentIndex + 1) % sliderItemsLength;
sliderItems[currentIndex].classList.add('is-active');
}
function advance() {
isPaused = false;
if ((isPaused = false) = 1) {
setInterval(function() {
nextSlide();
}, 3000);
}
}
sliderBtnPrev.addEventListener('click', function() {
prevSlide();
});
sliderBtnNext.addEventListener('click', function() {
nextSlide();
});
slider.addEventListener('mouseover', function() {
isPaused = true;
});
slider.addEventListener('mouseout', function() {
isPaused = false;
});
advance();
// On press next, change slide
// sliderItems.forEach(function(sliderItem) {
// sliderItem.style.display = "none";
// });
// function prevSlide() {
// console.log('prev slide');
// }
// function nextSlide() {
// console.log('next slide');
// // if (currentIndex) {
// // console.log(sliderItems[currentIndex])
// // }
// // sliderItemsLength.push[1];
// // currentIndex + 1;
// // console.log(currentIndex < (sliderItemsLength + 1));
// // console.log(sliderItems[currentIndex + 1])
// // if (sliderItemsLength < -1) {
// // sliderItemsLength++;
// // }
// // if (currentIndex < (sliderItemsLength + 1)) {
// // sliderItems[currentIndex].classList.add('is-active');
// // }
// // if (numbers.length > 3) {
// // numbers.length = 3;
// // }
// // myArray[myArray.length - 1] + 1
// if (currentIndex < (sliderItemsLength + 1)) {
// sliderItems[currentIndex].classList.add('is-active');
// currentIndex++;
// } else {
// sliderItems.style.display = "none";
// }
// }
});
* {
box-sizing: border-box;
}
ul,
ol {
margin: 0;
padding: 0;
list-style: none;
}
.slider {
position: relative;
height: 350px;
width: 100%;
}
.slider__list {
height: 100%;
overflow: hidden;
position: relative;
}
.slider__item {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
display: none;
height: 100%;
width: 100%;
position: absolute;
}
.slider__item.is-active {
display: flex;
}
.slider__item:first-child {
background-color: orange;
}
.slider__item:nth-child(2) {
background-color: gold;
}
.slider__item:last-child {
background-color: green;
}
.slider__title {
color: white;
font-weight: bold;
font-size: 1.5em;
}
.slider__buttons {
position: absolute;
right: 0;
left: 0;
top: 50%;
}
.slider__buttons--prev {
height: 40px;
width: 40px;
background-color: red;
cursor: pointer;
position: absolute;
bottom: 0;
margin: auto;
top: 0;
left: 30px;
}
.slider__buttons--next {
height: 40px;
width: 40px;
background-color: red;
cursor: pointer;
position: absolute;
bottom: 0;
top: 0;
margin: auto;
right: 30px;
}
<div class="container">
<div class="slider">
<ul class="slider__list">
<li class="slider__item is-active">
<span class="slider__title">1</span>
</li>
<li class="slider__item">
<span class="slider__title">2</span>
</li>
<li class="slider__item">
<span class="slider__title">3</span>
</li>
</ul>
<div class="slider__buttons">
<span class="slider__buttons--prev"></span>
<span class="slider__buttons--next"></span>
</div>
<!-- <ul class="slider__nav">
<li class="slider__nav-item"></li>
<li class="slider__nav-item"></li>
<li class="slider__nav-item"></li>
</ul> -->
</div>
</div>
You need to hide all slides by default display: none then define a class is-active to change the display to flex
Start counting from -1
The formula to calculate the next slide is :
(currentIndex + 1) % sliderItemsLength
The formula to calculate the prev slide is :
(currentIndex + sliderItemsLength - 1) % sliderItemsLength
document.addEventListener('DOMContentLoaded', function() {
var sliderList = document.querySelector(".slider__list"),
sliderItems = document.querySelectorAll(".slider__item"),
sliderBtnPrev = document.querySelector(".slider__buttons--prev"),
sliderBtnNext = document.querySelector(".slider__buttons--next"),
sliderItemsLength = sliderItems.length,
currentIndex = -1;
function prevSlide() {
sliderItems[currentIndex].classList.remove('is-active');
currentIndex = (currentIndex + sliderItemsLength - 1) % sliderItemsLength;
sliderItems[currentIndex].classList.add('is-active');
}
function nextSlide() {
if (currentIndex > 0) sliderItems[currentIndex].classList.remove('is-active');
else sliderItems[0].classList.remove('is-active');
currentIndex = (currentIndex + 1) % sliderItemsLength;
sliderItems[currentIndex].classList.add('is-active');
}
sliderBtnPrev.addEventListener('click', function() {
prevSlide();
});
sliderBtnNext.addEventListener('click', function() {
nextSlide();
});
nextSlide();
});
* {
box-sizing: border-box;
}
ul,
ol {
margin: 0;
padding: 0;
list-style: none;
}
.slider {
position: relative;
height: 350px;
width: 100%;
}
.slider__list {
height: 100%;
overflow: hidden;
position: relative;
}
.slider__item {
display: none;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
height: 100%;
width: 100%;
position: absolute;
}
.slider__item.is-active {
display: flex;
}
.slider__item:first-child {
background-color: orange;
}
.slider__item:nth-child(2) {
background-color: red;
}
.slider__item:last-child {
background-color: green;
}
.slider__title {
color: white;
font-weight: bold;
font-size: 1.5em;
}
.slider__buttons {
position: absolute;
right: 0;
left: 0;
top: 50%;
}
.slider__buttons--prev {
height: 40px;
width: 40px;
background-color: red;
cursor: pointer;
position: absolute;
bottom: 0;
margin: auto;
top: 0;
left: 30px;
}
.slider__buttons--next {
height: 40px;
width: 40px;
background-color: red;
cursor: pointer;
position: absolute;
bottom: 0;
top: 0;
margin: auto;
right: 30px;
}
<div class="container">
<div class="slider">
<ul class="slider__list">
<li class="slider__item">
<span class="slider__title">1</span>
</li>
<li class="slider__item">
<span class="slider__title">2</span>
</li>
<li class="slider__item">
<span class="slider__title">3</span>
</li>
</ul>
<div class="slider__buttons">
<span class="slider__buttons--prev"></span>
<span class="slider__buttons--next"></span>
</div>
<!-- <ul class="slider__nav">
<li class="slider__nav-item"></li>
<li class="slider__nav-item"></li>
<li class="slider__nav-item"></li>
</ul> -->
</div>
</div>
I'm building a simple flexbox navigation, when the screen size is below 980px a mobile version of the menu shows.
I'm building the javascript to do this - does anyone know why my console.log message won't show when the mobile version of the menu is clicked?
It's driving me around the twist.
You have to reduce the window below 980px to see what i mean.
https://codepen.io/emilychews/pen/eezYox?editors=1111
var mobileMenuButton = document.querySelector('#mobile-menu')
var mobileMenuItems = document.querySelector('#nav-menu')
// TOGGLE MOBILE MENU
var mobileMenu = false
if (mobileMenu === false) {
function showMobileMenu() {
mobileMenuButton.onclick(function() {
console.log("clicked");
})
mobileMenu = true
}
}
* {
padding: 0;
margin: 0;
}
p {
color: white;
}
header {
width: 100%;
}
#main-nav {
width: inherit;
height: 100px;
background: red;
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding: 10px 5% 10px 5%;
align-items: center;
}
#logo-wrapper {
width: 150px;
height: 75px;
background-color: grey;
}
#nav-menu {
display: flex;
margin-left: auto;
}
#main-nav ul li {
list-style-type: none;
padding: 5px 10px;
background: pink;
margin: 0 5px;
}
#mobile-menu {
display: none;
}
#media only screen and (max-width: 980px) {
#mobile-menu {
display: block;
background: blue;
padding: 5px 10px;
box-sizing: border-box;
cursor: pointer;
z-index: 99;
}
#main-nav ul {
display: none;
}
}
<header>
<nav id="main-nav">
<div id="logo-wrapper"></div>
<ul id="nav-menu">
<li class="menu-item menu-item-1"><a>Home</a></li>
<li class="menu-item menu-item-2"><a>About</a></li>
<li class="menu-item menu-item-3"><a>Contact</a></li>
</ul>
<div id="mobile-menu"><a>Menu</a></div>
</nav>
</header>
Well there are few problems, You never call showMobileMenufunction, so event is never binded to that element. onclick is not a function. I believe You want something like:
var mobileMenuButton = document.querySelector('#mobile-menu')
var mobileMenuItems = document.querySelector('#nav-menu')
// TOGGLE MOBILE MENU
var mobileMenu = false
mobileMenuButton.addEventListener('click', function() {
toggleMobileMenu();
})
function toggleMobileMenu() {
if (mobileMenu === false) {
console.log("clicked");
mobileMenu = true
} else {
console.log("not clicked");
mobileMenu = false
}
}