How to run the same Javascript function for more than one div

Asked

Viewed 36 times

-1

I have a slide carousel and I need to play this same carousel (only with different images and sections) on the same page. I will make this application for a blog, so there are several categories that will have several posts being "scrolados".

The problem is that this carousel is only working on the first div, he does not perform in divs remaining.

Can give me tips on what to do?

I have set up a simple structure here to illustrate what I have done so far:

<style>
body {
  margin: 0px;
}

ul {
  padding: 0px;
  margin: 0px;
  list-style: none;
}

img {
  display: block;
  max-width: 100%;
}

.slide-wrapper {
  overflow: hidden;
}

.slide {
  display: flex;
}

.slide article {
  flex-shrink: 0;
  width: 80vw;
  max-width: 800px;
  margin: 0 20px;
}
</style>

<div class="slide-wrapper">
       <div class="slide">
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
       </div>
     </div>   

     <div class="slide-wrapper">
       <div class="slide">
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
       </div>
     </div>

    <div class="slide-wrapper">
       <div class="slide">
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
        <article><img src="https://unsplash.com/photos/1U0xyCNniTs" alt=""></article>
       </div>
     </div>

<script>
class Slide {
  constructor(slide, wrapper) {
    this.slide = document.querySelector(slide)
    this.wrapper = document.querySelector(wrapper);
    this.dist = { finalPosition: 0, startX: 0, movement: 0 }
  }

  moveSlide(distX) {
    this.dist.movePosition = distX;
    this.slide.style.transform = `translate3d(${distX}px, 0, 0)`;
  }

  updatePosition(clientX) {
    this.dist.movement = (this.dist.startX - clientX) * 1.6;
    return this.dist.finalPosition - this.dist.movement;
  }

  onStart(event) {
    let movetype;
    if (event.type === 'mousedown') {
      this.dist.startX = event.clientX;
      movetype = 'mousemove';
    } else {
      this.dist.startX = event.changedTouches[0].clientX;
      movetype = 'touchmove';
    }
    this.wrapper.addEventListener(movetype, this.onMove);
  }

  onMove(event) {
    const pointerPosition = (event.type === 'mousemove') ? event.clientX : event.changedTouches[0].clientX;
    const finalPosition = this.updatePosition(pointerPosition);
    this.moveSlide(finalPosition);
  }

  onEnd(event) {
    const movetype = (event.type === 'mouseup') ? 'mousemove' : 'touchmove';
    this.wrapper.removeEventListener(movetype, this.onMove);
    this.dist.finalPosition = this.dist.movePosition;
  }

  addSlideEvents() {
    this.wrapper.addEventListener('mousedown', this.onStart);
    this.wrapper.addEventListener('touchstart', this.onStart);
    this.wrapper.addEventListener('mouseup', this.onEnd);
    this.wrapper.addEventListener('touchend', this.onEnd);
  }

  bindEvents() {
    this.onStart = this.onStart.bind(this);
    this.onMove = this.onMove.bind(this);
    this.onEnd = this.onEnd.bind(this);
  }

  init() {
    this.bindEvents();
    this.addSlideEvents();
    return this;
  }
}


const slide = new Slide('.slide', '.slide-wrapper');
slide.init();
</script>

2 answers

2

Your problem has to do with document.querySelector within the constructor class Slide. It returns only 1 DOM element, then it returns only the first div.

You’d have to use the document.querySelectorAll and rewrite the code to, in addition to assigning distinct classes or ids to each div, so that each section responds independently to mouse events.

Or you can solve it in the fastest, most direct, and most common way. Add a different class by following each slide-wrapper and slide.

For example:

  • First div:
<div class="slide-wrapper first">
      <div class="slide fist">
      ....
  • Second div:
<div class="slide-wrapper second">
      <div class="slide second">
      ....
  • Third div:
<div class="slide-wrapper third">
      <div class="slide third">
      ....

and then assign the class instance Slide for each of the divs:

const slide = new Slide('.first', '.first');
const slide2 = new Slide('.second', '.second');
const slide3 = new Slide('.third', '.third');

slide.init();
slide2.init();
slide3.init();

I think it’s a clever solution, because I think the best thing would be to rewrite the code, but see if it works the way you expect it to:

       class Slide {
        constructor(slide, wrapper) {
          this.slide = document.querySelector(slide);
          this.wrapper = document.querySelector(wrapper);
          this.dist = { finalPosition: 0, startX: 0, movement: 0 };
        }

        moveSlide(distX) {
          this.dist.movePosition = distX;
          this.slide.style.transform = `translate3d(${distX}px, 0, 0)`;
        }

        updatePosition(clientX) {
          this.dist.movement = (this.dist.startX - clientX) * 1.6;
          return this.dist.finalPosition - this.dist.movement;
        }

        onStart(event) {
          let movetype;
          if (event.type === 'mousedown') {
            this.dist.startX = event.clientX;
            movetype = 'mousemove';
          } else {
            this.dist.startX = event.changedTouches[0].clientX;
            movetype = 'touchmove';
          }
          this.wrapper.addEventListener(movetype, this.onMove);
        }

        onMove(event) {
          const pointerPosition =
            event.type === 'mousemove'
              ? event.clientX
              : event.changedTouches[0].clientX;
          const finalPosition = this.updatePosition(pointerPosition);
          this.moveSlide(finalPosition);
        }

        onEnd(event) {
          const movetype = event.type === 'mouseup' ? 'mousemove' : 'touchmove';
          this.wrapper.removeEventListener(movetype, this.onMove);
          this.dist.finalPosition = this.dist.movePosition;
        }

        addSlideEvents() {
          this.wrapper.addEventListener('mousedown', this.onStart);
          this.wrapper.addEventListener('touchstart', this.onStart);
          this.wrapper.addEventListener('mouseup', this.onEnd);
          this.wrapper.addEventListener('touchend', this.onEnd);
        }

        bindEvents() {
          this.onStart = this.onStart.bind(this);
          this.onMove = this.onMove.bind(this);
          this.onEnd = this.onEnd.bind(this);
        }

        init() {
          this.bindEvents();
          this.addSlideEvents();
          return this;
        }
      }

      const slide = new Slide('.first', '.first');
      const slide2 = new Slide('.second', '.second');
      const slide3 = new Slide('.third', '.third');

      slide.init();
      slide2.init();
      slide3.init();
body {
      margin: 0px;
    }

    ul {
      padding: 0px;
      margin: 0px;
      list-style: none;
    }

    img {
      display: block;
      max-width: 100%;
    }

    .slide-wrapper {
      overflow: hidden;
    }

    .slide {
      display: flex;
    }

    .slide article {
      flex-shrink: 0;
      width: 80vw;
      max-width: 200px;
      margin: 0 20px;
    }
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div class="slide-wrapper first">
      <div class="slide fist">
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
      </div>
    </div>

    <div class="slide-wrapper second">
      <div class="slide second">
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
      </div>
    </div>

    <div class="slide-wrapper third">
      <div class="slide third">
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
        <article>
          <img
            src="https://images.theconversation.com/files/350865/original/file-20200803-24-50u91u.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=1200&h=675.0&fit=crop"
            alt=""
          />
        </article>
      </div>
    </div>
  </body>
</html>

1

Use querySelectorAll, return a list of all the elements that answer the query

slides = [];
//retornara um nodeList...
var nodes = querySelectorAll('.slide-wrapper');
for (var i = 0, e = nodes.length; i < e; i++) {
  //passa o elemento para o construtor
  slides.push(new Slide(nodes[i]));
}

*Obs.: you can also convert the nodeList to array with "Array.prototype.Slice.call(nodeList)" and call a foreach

and with a small adaptation in the builder, it is ready to receive the wrapper element:

  constructor(slide_wrapper) {
    this.slide = slide_wrapper.querySelector('.slide');//<pega o .slide que está dentro do wrapper
    this.wrapper = slide_wrapper;//<
    this.dist = { finalPosition: 0, startX: 0, movement: 0 };
  }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.