Create A carousel The interesting parts How to hide the container’s scrollbar? How to scroll to a specific element? How to make a loop carousel?
A carousel is used to crycle through elements:
Create A carousel Step 1. Add HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <div class ="parentEl" > <div id ="container" > <div class ="item" > 1</div > <div class ="item" > 2</div > <div class ="item" > 3</div > <div class ="item" > 4</div > <div class ="item" > 5</div > <div class ="item" > 6</div > <div class ="item" > 7</div > </div > <div class ="controls" > <button class ="toggle" data-toggle ="prev" > Prev</button > <button class ="toggle" data-toggle ="next" > Next</button > </div > <div class ="dots" style ="text-align: center" > </div > </div >
Step 2. Add CSS:
Style the next and previous buttons, and the dots:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #container {scroll-snap-type : x mandatory;display : flex;overflow-x : scroll;width : 100% ;} .item {border : 1px solid red;min-width : 33% ;height : auto;scroll-snap-align : start;} #container {scroll-behavior: smooth; } #container ::-webkit-scrollbar {display : none;} #container {-ms-overflow -style: none; scrollbar-width : none; } .controls { padding : 1em ; text-align : center; } .controls button { background : #aaa ; border : 0 ; border-radius : 0.25em ; color : #eee ; padding : 0.5em 1em ; } .controls button :hover ,.controls button :focus { background : orange; } .dot { cursor : pointer; height : 13px ; width : 13px ; margin : 0 2px ; background-color : #bbb ; border-radius : 50% ; display : inline-block; transition : background-color 0.6s ease; } .active , .dot :hover { background-color : #717171 ; }
Step 3. Add JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 const parentEl = document .querySelector ('.parentEl' );const container = document .querySelector ('#container' );const dotsWrapperEl = document .querySelector ('.dots' );const items = container.querySelectorAll ('.item' );const nextBtn = parentEl.querySelector ('.controls [data-toggle="next"]' );const prevBtn = parentEl.querySelector ('.controls [data-toggle="prev"]' );let currentIndex = 0 ;nextBtn.addEventListener ('click' , function (e ) { currentIndex = (currentIndex + 1 ) % items.length ; updateUI (); }); prevBtn.addEventListener ('click' , function (e ) { currentIndex--; if (currentIndex < 0 ) currentIndex = items.length - 1 ; updateUI (); }); dotsWrapperEl.addEventListener ('click' , function (e ) { const target = e.target ; const dotList = dotsWrapperEl.querySelectorAll ('.dot' ); if (target.classList .contains ('dot' )) { const index = getDotIndex (target, dotList); currentIndex = index; updateUI (); } }); function getDotIndex (target, dotList ) { for (let i = 0 ; i < dotList.length ; i++) { if (dotList[i] === target) return i; } return -1 ; } function updateUI ( ) { dotsWrapperEl.querySelector ('.active' )?.classList .remove ('active' ); dotsWrapperEl.querySelectorAll ('.dot' )[currentIndex].classList .add ('active' ); const ar = getOrder (currentIndex); for (let i = 0 ; i < items.length ; i++) { items[i].style .order = ar[i]; } items[currentIndex].scrollIntoView ({block : "start" , inline : "start" }); } function getOrder (rotateCount = 0 ) { const arr = Array .from ({length : items.length }, (x, i ) => i + 1 ); arr.push (arr.shift ()); if (rotateCount == 0 ) return arr; const ar = arr.splice (items.length - rotateCount, rotateCount); arr.splice (0 , 0 , ...ar); return arr; } getOrder ();dotsWrapperEl.innerHTML = '<span class="dot"></span>' .repeat (items.length ); updateUI ();
The interesting parts 1 2 3 4 5 6 7 8 9 10 11 12 #container ::-webkit-scrollbar { display : none; } #container { -ms-overflow -style: none; scrollbar-width : none; }
There are several ways of scrolling to an element on the web page, we prefer the Element interface’s scrollIntoView()
method here.
How to make a loop carousel? We are using CSS Scroll Snap rather than other approaches to make slides scrollable, this module does not support loop by default. We could leverage the order
CSS property in the flexbox layout to control the orders of slides in the carousel, which is a clever solution.
To determine the order of each item, we use a simple algorithm here:
1 2 3 4 5 6 7 8 function getOrder (rotateCount = 0 ) { const arr = Array .from ({length : items.length }, (x, i ) => i + 1 ); arr.push (arr.shift ()); if (rotateCount == 0 ) return arr; const ar = arr.splice (items.length - rotateCount, rotateCount); arr.splice (0 , 0 , ...ar); return arr; }
All the slides are given an order
CSS property with corresponding value, note the first one has a value of 2
instead of 1
by default. Please see LeetCode 189. Rotate Array