2

How to attach an event listener to all div's with the same class name?

In the below example I'm trying to add a class name scroll-x to a div so it can get the horizontal scrolling feature by running the JS code. But the JS code works on only first div.

Here is a pen https://codepen.io/Code3ater/pen/wvGYKvO?editors=0010

const scrollArea = document.querySelector(".scroll-x");
let isDown = false;
let startX;
let scrollLeft;

scrollArea.addEventListener("mousedown", (e) => {
  isDown = true;
  scrollArea.classList.add("active");
  startX = e.pageX - scrollArea.offsetLeft;
  scrollLeft = scrollArea.scrollLeft;
});
scrollArea.addEventListener("mouseleave", () => {
  isDown = false;
  scrollArea.classList.remove("active");
});
scrollArea.addEventListener("mouseup", () => {
  isDown = false;
  scrollArea.classList.remove("active");
});
scrollArea.addEventListener("mousemove", (e) => {
  if (!isDown) return;
  e.preventDefault();
  const x = e.pageX - scrollArea.offsetLeft;
  const walk = (x - startX) * 3; //scroll-fast
  scrollArea.scrollLeft = scrollLeft - walk;
});
  • `[...querySelectorAll('.sroll-x')].map(el => el.addEventListener('event', fn))` – Denis Tsoi Sep 19 '20 at 03:40
  • 1
    Use [event delegation](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_delegation) instead of assigning multiple events — it’s more maintainable, and applies to dynamically added elements. E.g., use an [event argument](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#The_event_listener_callback)’s [`target`](https://developer.mozilla.org/en-US/docs/Web/API/Event/target). See [the tag info](https://stackoverflow.com/tags/event-delegation/info) and [What is DOM Event delegation?](https://stackoverflow.com/q/1687296/4642212). – Sebastian Simon Sep 19 '20 at 04:00

2 Answers2

1

You should change selection as below:

const scrollAreas = document.querySelectorAll(".scroll-x");

Then to attach eventListener

scrollAreas.forEach((scrollArea)=>scrollArea.addEventListener("mousedown", (e) => {
//Code goes here
}));
Asutosh
  • 1,632
  • 2
  • 13
  • 21
0

Try putting it all in a for loop, and use a counter to access each element. Use this inside the callback functions to access the element.

const scrollArea = document.querySelector(".scroll-x");
let isDown = false;
let startX;
let scrollLeft;
let length = scrollArea.length;

for (let i = 0; i < length; i++) {
    scrollArea[i].addEventListener("mousedown", (e) => {
        isDown = true;
        this.classList.add("active");
        startX = e.pageX - this.offsetLeft;
        scrollLeft = this.scrollLeft;
    });
    scrollArea[i].addEventListener("mouseleave", () => {
        isDown = false;
        this.classList.remove("active");
    });
    scrollArea[i].addEventListener("mouseup", () => {
        isDown = false;
        this.classList.remove("active");
    });
    scrollArea[i].addEventListener("mousemove", (e) => {
        if (!isDown) return;
        e.preventDefault();
        const x = e.pageX - this.offsetLeft;
        const walk = (x - startX) * 3; //scroll-fast
        this.scrollLeft = scrollLeft - walk;
    });
}

edddd
  • 167
  • 8