0

I would like to do this automaticaly (exp I would like to have an array which contains modal-bg1 to modal-bg9...), is there a way to do it ? :

var modalBtn = [document.querySelectorAll(".activeModal1"), document.querySelectorAll(".activeModal2")];
var modalBg = [document.querySelector(".modal-bg1"), document.querySelector(".modal-bg2")];
const prevBtn = [document.querySelector("#prevBtn1"), document.querySelector("#prevBtn2")];
const nextBtn = [document.querySelector("#nextBtn1"), document.querySelector("#nextBtn2")];
const carouselSlide = [document.querySelector(".carousel-slide1"), document.querySelector(".carousel-slide2")];
const carouselImages = [document.querySelectorAll(".imgSlide1"),document.querySelectorAll(".imgSlide2")];
3
  • 2
    "Code Smell" Why do you need this? Maybe if you built code to not need the classname it would go away. Commented Mar 17, 2021 at 17:05
  • Because I need to apply a function on each one of those elements, like so : modalBtn.forEach((e)=>{ do smthing with e })) Commented Mar 17, 2021 at 17:08
  • So change the code to do look ups inside of the element. If you want to build something that can be used more than once on a page, it is a good idea to build something that works with a single reference so you do not find yourself doing stuff like this that relies on unique identifiers. We can make this work, but there is a better solution out there. Commented Mar 17, 2021 at 17:09

2 Answers 2

2

A better way to handle multiple modals is to let each button know how to query for its own modal i.e. data-controls. You can then provide an index e.g. data-index to get the correct modal.

All your queries to get the buttons and slides should be relative to the current modal.

const handleClick = e => {
  const
    btn = e.target,
    index = parseInt(btn.dataset.index, 10),
    modal = document.querySelectorAll(btn.dataset.controls)[index];
  
  document.querySelectorAll('.modal').forEach(currModal =>
    currModal.classList.toggle('active', currModal === modal));
  
  // Relative queries
  const
    carouselSlide = modal.querySelector('.carousel-slide'),
    carouselImages = modal.querySelector('.carousel-images'),
    prevBtn = modal.querySelector('.prev-btn'),
    nextBtn = modal.querySelector('.next-btn');
};

document.querySelectorAll('.modal-btn').forEach(btn =>
  btn.addEventListener('click', handleClick));
body {
  display: flex;
  flex-direction: column;
}

.modal {
  display: none;
  width: 10em;
  height: 6em;
  border: thin solid grey;
  padding: 0.25em;
}

.modal-background {
  display: flex;
  flex-direction: column;
  flex: 1;
}

.carousel-slide {
  display: flex;
  flex: 1;
  background: grey;
}

.carousel-images {
  display: flex;
  flex: 1;
  justify-content: center;
  font-size: 3em;
  color: lightgrey;
}

.modal-buttons {
  display: flex;
  justify-content: space-between;
  margin-top: 0.25em;
}

.modal.active {
  display: flex;
}
<div>
  <button class="modal-btn" data-controls=".modal" data-index="0">Show 1</button>
  <button class="modal-btn" data-controls=".modal" data-index="1">Show 2</button>
  <button class="modal-btn" data-controls=".modal" data-index="2">Show 3</button>
</div>

<hr />

<div class="modal">
  <div class="modal-background">
    <div class="carousel-slide">
      <div class="carousel-images">#1</div>
    </div>
    <div class="modal-buttons">
      <button class="prev-btn">Prev</button>
      <button class="next-btn">Next</button>
    </div>
  </div>
</div>

<div class="modal">
  <div class="modal-background">
    <div class="carousel-slide">
      <div class="carousel-images">#2</div>
    </div>
    <div class="modal-buttons">
      <button class="prev-btn">Prev</button>
      <button class="next-btn">Next</button>
    </div>
  </div>
</div>

<div class="modal">
  <div class="modal-background">
    <div class="carousel-slide">
      <div class="carousel-images">#3</div>
    </div>
    <div class="modal-buttons">
      <button class="prev-btn">Prev</button>
      <button class="next-btn">Next</button>
    </div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

0

This function will take the selector and the amount and generate an array:

function createArray(selector, count) {
    var current = 0;
    var arr = []
    while (++current < count) {
        arr.push(document.querySelector(selector.replace(/\{#\}/g, current)));
    }
    return arr;
}

In the selector {#} will be replaced with the number:

var modalBtn = createArray(".activeModal{#}");

EDIT: If you want to have all elements with class .activeModal followed by any number, you can simply use the attribute starts with selector:

var modalBtn = document.querySelectorAll('[class^="activeModal"]');

That will return a list of all elements.

7 Comments

Try educating yourself about template literals. `.activeModal${current}`.
They cannot be used here, because createArray takes a dynamic selector string, and otherwise I would have to use generator functions.
Thanks ! And what do you put in count parameter ? How do you kind the number of time a class with activeModal appears ?
`${selector}${current}` Really no need for string manipulation and regexes here.
That is exactly the count parameter. If you have 9 elements, you have to set the parameter to 9 etc.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.