ItzaMi
ItzaMi

Reputation: 367

Creating a text slider with vanilla JS with clickable arrows

I think I need to use a loop somewhere but I'm not sure on how to translate it to my code so if someone could help me, I would appreciate it.

I have 3 blocks of text that I want to display while using two arrows to switch between the text. I figured that I should use "display: none" for the 2 blocks of text that I'm not currently displaying.

I also realize that I should probably use some kind of loop related with the number of text blocks that I have but I've not been able to translate that into my code since I'm fairly new to this still.

Figured I could create the variables for each text block and then add them to an array (not even sure if that's allowed). After that I would evaluate the .length of the array to make the arrows click. I would very much appreciate if someone could help me with this! I would also appreciate if the answer could be given in regular JS only.

Here's the codepen: https://codepen.io/ItzaMi/pen/ZPMXYw

var scrollArrowRight = document.getElementById("scroll-arrow-right");
var scrollArrowLeft = document.getElementById("scroll-arrow-left");

var par1 = document.getElementById("p-1");
var par2 = document.getElementById("p-2");
var par3 = document.getElementById("p-3");

var slider = [par1, par2, par3];

scrollArrowRight.onclick = function() {
  par2.style.display = "block";
  par1.style.display = "none";
}

scrollArrowLeft.onclick = function() {
  par2.style.display = "none";
  par3.style.display = "block";
}
#scroll-join {
  display: flex;
  justify-content: center;
  align-content: center;
  align-items: center;
  flex-direction: row;
}

.scroll-arrow {
  margin: 0 0.6em;
  font-size: 1.4em;
}

#p-2 {
  display: none;
}

#p-3 {
  display: none;
}
<div id="scroll-join">
  <i class="fas fa-caret-left scroll-arrow" id="scroll-arrow-left"></i>
  <p class="join-p" id="p-1">WLorem ipsum dolor sit amet.</p>
  <p class="join-p" id="p-2">Lorem ipsum dolor sit amet</p>
  <p class="join-p" id="p-3">WLorem ipsum dolor sit amet.</p>
  <i class="fas fa-caret-right scroll-arrow" id="scroll-arrow-right"></i>
</div>

Upvotes: 3

Views: 1702

Answers (3)

ForScale
ForScale

Reputation: 1

const [arrowLeft, arrowRight] = document.querySelectorAll(".container .arrow");

const textBoxes = document.querySelectorAll(".text-box");

textBoxes.howFarTranslated = -100;

function handleArrowClick() {
  if (this === arrowLeft && textBoxes.howFarTranslated > -200) {
    textBoxes.howFarTranslated -= 100;
  } else if (this === arrowRight && textBoxes.howFarTranslated < 0) {
    textBoxes.howFarTranslated += 100;
  }

  arrowLeft.disabled = textBoxes.howFarTranslated === -200;
  arrowRight.disabled = textBoxes.howFarTranslated === 0;

  textBoxes.forEach(
    textBox =>
    (textBox.style.transform = `translateX(${textBoxes.howFarTranslated}%)`)
  );
}

[arrowLeft, arrowRight].forEach(arrow =>
  arrow.addEventListener("click", handleArrowClick)
);
body {
  margin: 0;
  padding-top: 64px;
}

body,
body * {
  box-sizing: border-box;
}

.container {
  display: flex;
  width: 50%;
  height: 54px;
  min-width: 320px;
  margin: auto;
}

.container .arrow {
  flex: 1;
  min-width: 64px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  outline: none;
}

.container .arrow:hover:not([disabled]) {
  box-shadow: 0 2px 8px #666;
}

.container .arrow:active {
  transform: scale(0.95);
}

.container .arrow[disabled] {
  opacity: 0.25;
  cursor: initial;
}

.container .display-box {
  flex: 5;
  font-size: 0;
  white-space: nowrap;
  overflow: hidden;
}

.container .display-box .text-box {
  position: relative;
  z-index: -1;
  display: inline-flex;
  width: 100%;
  height: 100%;
  text-align: center;
  transform: translateX(-100%);
  transition: transform 333ms linear;
}

.container .display-box .text-box p {
  margin: auto;
  font-size: 24px;
}
<div class="container">
  <button class="arrow left-arrow"><</button>
  <div class="display-box">
    <div class="text-box text-0">
      <p>Text 0 text 0 text 0 text 0</p>
    </div>
    <div class="text-box text-1">
      <p>Text 1 text 1 text 1 text 1</p>
    </div>
    <div class="text-box text-2">
      <p>Text 2 text 2 text 2 text 2</p>
    </div>
  </div>
  <button class="arrow right-arrow">></button>
</div>

Upvotes: 0

Keno
Keno

Reputation: 2098

Here's another way in which you could implement the slider. Define a 'current index' which is updated when you click between the slides. Since you're using an array of slides I think this would be a bit more suitable.

var scrollArrowRight = document.getElementById("scroll-arrow-right");
var scrollArrowLeft = document.getElementById("scroll-arrow-left");

var par1 = document.getElementById("p-1");
var par2 = document.getElementById("p-2");
var par3 = document.getElementById("p-3");

var slider = [par1, par2, par3];
var currentIndex = -1;

//On load, show the first slide
loadPage(0);

function loadPage(i) {
  //Check if index is valid
  if (slider[i]) {
    slider[i].removeAttribute('hidden');
  } else {
    return;
  }

  //Hide previous slide
  if (slider[currentIndex]) {
    slider[currentIndex].setAttribute('hidden', '');
  }

  currentIndex = i;
}

scrollArrowRight.onclick = function() {
  loadPage(currentIndex + 1);
}

scrollArrowLeft.onclick = function() {
  loadPage(currentIndex - 1);
}
#scroll-join {
  display: flex;
  justify-content: center;
  align-content: center;
  align-items: center;
  flex-direction: row;
}

.scroll-arrow {
  cursor: pointer;
  margin: 0 0.6em;
  font-size: 1.4em;
}
<div id="scroll-join">
  <i class="fas fa-caret-left scroll-arrow" id="scroll-arrow-left">←</i>
  <p class="join-p" id="p-1" hidden>WLorem ipsum dolor sit amet.</p>
  <p class="join-p" id="p-2" hidden>Lorem ipsum dolor sit amet</p>
  <p class="join-p" id="p-3" hidden>WLorem ipsum dolor sit amet.</p>
  <i class="fas fa-caret-right scroll-arrow" id="scroll-arrow-right">→</i>
</div>

Upvotes: 1

mmshr
mmshr

Reputation: 947

You can achieve the text slider by setting an active class for the current active element, and displaying the next/previous element based on which element as active when the arrow is clicked. I wrote a working example with this idea:

var scrollArrowRight = document.getElementById("scroll-arrow-right");
var scrollArrowLeft = document.getElementById("scroll-arrow-left");

scrollArrowRight.onclick = function() {
  // get current active element
  var active = document.querySelector(".active");
  // add active class to next sibling      
  active.nextElementSibling.classList.add("active");
  // get all active elements
  var allActive = document.querySelectorAll(".active");
  // remove active class from first element
  allActive[0].classList.remove("active");
}

scrollArrowLeft.onclick = function() { 
  // get current active element
  var active = document.querySelector(".active");
  // add active class to previous sibling
  active.previousElementSibling.classList.add("active");
  // get all active elements
  var allActive = document.querySelectorAll(".active");
  // remove active class from second element
  allActive[1].classList.remove("active");
}
#scroll-join {
   display: flex;
   justify-content: center;
   align-content: center;
   align-items: center;
   flex-direction: row;
}

.scroll-arrow {
  margin: 0 0.6em;
  font-size: 1.4em;
}

.join-p {
  display: none; 
 }

.active {
  display: block;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css">

<div id="scroll-join">
    <i class="fas fa-caret-left scroll-arrow" id="scroll-arrow-left"></i>
    <div>
      <p class="join-p active">1 Lorem ipsum dolor amet.</p>
      <p class="join-p">2 Lorem ipsum dolor sit amet</p>
      <p class="join-p">3 Lorem ipsum dolor sit amet</p>
    </div>
    <i class="fas fa-caret-right scroll-arrow" id="scroll-arrow-right"></i>
</div>

Hope that helps get you started!

Upvotes: 1

Related Questions