Matrion
Matrion

Reputation: 135

disable left or right arrow at the last item

Just made a simple div slider with navigation arrows. The div slider works just fine, except, I want some sort of CSS styling to be applied to the arrows.

That is, when a user clicks the left or right arrow, up to the last item, apply CSS styling telling the user they've reached the end of the slider.

let buttonLeft = document.getElementById('slide_left')
let buttonRight = document.getElementById('slide_right')

let container = document.getElementById('slider')

buttonLeft.addEventListener('click', function() {
  container.scrollLeft -= 90
})

buttonRight.addEventListener('click', function() {
  container.scrollLeft += 90
})
body {
  background-color: #555;
  height: 100vh;
  display: grid;
  align-items: center;
  justify-items: center;
  font-family: 'Helvetica';
}

div#slide_wrapper {
  width: 440px;
  display: flex;
  justify-content: space-between;
  height: fit-content;
}

div#slider {
  width: 350px;
  display: flex;
  height: fit-content;
  flex-wrap: nowrap;
  overflow: hidden;
}

div.thumbnail {
  min-width: 80px;
  min-height: 80px;
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 30px;
}

div.thumbnail:not(:last-child) {
  margin-right: 10px;
}

div.thumbnail:nth-child(1) {
  background-color: darkturquoise;
}

div.thumbnail:nth-child(2) {
  background-color: goldenrod;
}

div.thumbnail:nth-child(3) {
  background-color: rebeccapurple;
}

div.thumbnail:nth-child(4) {
  background-color: powderblue;
}

div.thumbnail:nth-child(5) {
  background-color: firebrick;
}

div.thumbnail:nth-child(6) {
  background-color: sienna;
}

div.thumbnail:nth-child(7) {
  background-color: bisque;
}

div.thumbnail:nth-child(8) {
  background-color: navy;
}

div#slide_wrapper>button {
  height: fit-content;
  align-self: center;
  font-size: 24px;
  font-weight: 800;
  border: none;
  outline: none;
}

div#slide_wrapper>button:hover {
  cursor: pointer;
}
<div id="slide_wrapper">
  <button id="slide_left" class="slide_arrow">&#10094;</button>
  <div id="slider">
    <div class="thumbnail active">1</div>
    <div class="thumbnail">2</div>
    <div class="thumbnail">3</div>
    <div class="thumbnail">4</div>
    <div class="thumbnail">5</div>
    <div class="thumbnail">6</div>
    <div class="thumbnail">7</div>
    <div class="thumbnail">8</div>
  </div>
  <button id="slide_right" class="slide_arrow">&#10095;</button>
</div>

Upvotes: 1

Views: 725

Answers (2)

Lee Taylor
Lee Taylor

Reputation: 7994

Simply check to see if you need to disable each button based on the position of the scroll. Then if there is a need to disable a button, add the disabled class to the button, otherwise remove it.

Future enhancements.

  1. Remove the hardcoded 360 value for the scroll end. This should be calculated from the size of the carousel items and the width of the viewport.

  2. Allow more than one carousel to work with the same code. This could be achieved by using a javascript class that would hold the elements inside an object, separate from other carousels.

See the demo:

let buttonLeft = document.getElementById('slide_left')
let buttonRight = document.getElementById('slide_right')

let container = document.getElementById('slider')


let checkScroll = function() {
  if (container.scrollLeft <= 0)
    buttonLeft.classList.add("disabled");
  else
    buttonLeft.classList.remove("disabled");

  if (container.scrollLeft >= 360)
    buttonRight.classList.add("disabled");
  else
    buttonRight.classList.remove("disabled");
}

checkScroll();

buttonLeft.addEventListener('click', function() {
  container.scrollLeft -= 90;

  checkScroll();
})

buttonRight.addEventListener('click', function() {
  container.scrollLeft += 90;
  checkScroll();
})
body {
  background-color: #555;
  height: 100vh;
  display: grid;
  align-items: center;
  justify-items: center;
  font-family: 'Helvetica';
}

div#slide_wrapper {
  width: 440px;
  display: flex;
  justify-content: space-between;
  height: fit-content;
}

div#slider {
  width: 350px;
  display: flex;
  height: fit-content;
  flex-wrap: nowrap;
  overflow: hidden;
}

div.thumbnail {
  min-width: 80px;
  min-height: 80px;
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 30px;
}

div.thumbnail:not(:last-child) {
  margin-right: 10px;
}

div.thumbnail:nth-child(1) {
  background-color: darkturquoise;
}

div.thumbnail:nth-child(2) {
  background-color: goldenrod;
}

div.thumbnail:nth-child(3) {
  background-color: rebeccapurple;
}

div.thumbnail:nth-child(4) {
  background-color: powderblue;
}

div.thumbnail:nth-child(5) {
  background-color: firebrick;
}

div.thumbnail:nth-child(6) {
  background-color: sienna;
}

div.thumbnail:nth-child(7) {
  background-color: bisque;
}

div.thumbnail:nth-child(8) {
  background-color: navy;
}

div#slide_wrapper>button {
  height: fit-content;
  align-self: center;
  font-size: 24px;
  font-weight: 800;
  border: none;
  outline: none;
}

div#slide_wrapper>button:hover {
  cursor: pointer;
}

.slide_arrow.disabled {
  opacity: 0.2;
  cursor: auto !important;
}
<div id="slide_wrapper">
  <button id="slide_left" class="slide_arrow">&#10094;</button>
  <div id="slider">
    <div class="thumbnail active">1</div>
    <div class="thumbnail">2</div>
    <div class="thumbnail">3</div>
    <div class="thumbnail">4</div>
    <div class="thumbnail">5</div>
    <div class="thumbnail">6</div>
    <div class="thumbnail">7</div>
    <div class="thumbnail">8</div>
  </div>
  <button id="slide_right" class="slide_arrow">&#10095;</button>
</div>

Upvotes: 1

nissow
nissow

Reputation: 79

a simple solution to this is to actually create a css class that defines the style of arrows when there are no more items and then just add/remove class based on current index of items

Upvotes: 0

Related Questions