Home > OS >  Dynamic Javascript code for multiple elements
Dynamic Javascript code for multiple elements

Time:10-21

This script adds draggable feature to the slider, but the problem is that when we have more than one slider, only the first slider works and the rest fails. How can this script be changed so that any number of sliders on the page, each of them can be draggable separately and work properly ???

In fact, the goal is to define a class in the script instead of the id that by applying it to any slider element, the slider can be draggable ???

   document.addEventListener('DOMContentLoaded', function () {
      const ele = document.getElementById('container');
      ele.style.cursor = 'grab';

      let pos = { top: 0, left: 0, x: 0, y: 0 };

      const mouseDownHandler = function (e) {
        ele.style.cursor = 'grabbing';
        ele.style.userSelect = 'none';

        pos = {
          left: ele.scrollLeft,
          top: ele.scrollTop,
          // Get the current mouse position
          x: e.clientX,
          y: e.clientY,
        };

        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);
      };

      const mouseMoveHandler = function (e) {
        // How far the mouse has been moved
        const dx = e.clientX - pos.x;
        const dy = e.clientY - pos.y;

        // Scroll the element
        ele.scrollTop = pos.top - dy;
        ele.scrollLeft = pos.left - dx;
      };

      const mouseUpHandler = function () {
        ele.style.cursor = 'grab';
        ele.style.removeProperty('user-select');

        document.removeEventListener('mousemove', mouseMoveHandler);
        document.removeEventListener('mouseup', mouseUpHandler);
      };

      // Attach the handler
      ele.addEventListener('mousedown', mouseDownHandler);
    });
#container {
      margin: 50px auto;
      border: 2px solid #ccc;
      border-radius: 10px;
      display: flex;
      width: 80%;
      gap: 1rem;
    }

    .item {
      border: 1px solid #cbd5e0;
      font-size: 2.25rem;
    }

    small {
      width: 150px;
      height: 150px;
      align-items: center;
      display: flex;
      justify-content: center;
    }
<html lang="en">

<head>
  <meta charset="utf-8" />
  <title>HTML DOM - Drag to scroll</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="stylesheet" href="/css/demo.css" />
  <link rel="preconnect" href="https://fonts.gstatic.com" />
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter&family=Source Code Pro&display=swap" />

</head>

<body>

  <div id="container" style=" overflow: auto; padding: 1rem">

    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>

  </div>


<div id="container" style=" overflow: auto; padding: 1rem">

    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>

  </div>


</body>

</html>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You just need to use document.querySelectorAll to get all the elements you want instead of one, and wrap the rest of your functions in a forEach function:

document.addEventListener('DOMContentLoaded', function () {
    [...document.querySelectorAll('#container')].forEach(ele => {
        // your code
    });
});

document.addEventListener('DOMContentLoaded', function () {
    [...document.querySelectorAll('#container')].forEach(ele => {
        ele.style.cursor = 'grab';

        let pos = { top: 0, left: 0, x: 0, y: 0 };

        const mouseDownHandler = function (e) {
            ele.style.cursor = 'grabbing';
            ele.style.userSelect = 'none';

            pos = {
                left: ele.scrollLeft,
                top: ele.scrollTop,
                // Get the current mouse position
                x: e.clientX,
                y: e.clientY,
            };

            document.addEventListener('mousemove', mouseMoveHandler);
            document.addEventListener('mouseup', mouseUpHandler);
        };

        const mouseMoveHandler = function (e) {
            // How far the mouse has been moved
            const dx = e.clientX - pos.x;
            const dy = e.clientY - pos.y;

            // Scroll the element
            ele.scrollTop = pos.top - dy;
            ele.scrollLeft = pos.left - dx;
        };

        const mouseUpHandler = function () {
            ele.style.cursor = 'grab';
            ele.style.removeProperty('user-select');

            document.removeEventListener('mousemove', mouseMoveHandler);
            document.removeEventListener('mouseup', mouseUpHandler);
        };

        // Attach the handler
        ele.addEventListener('mousedown', mouseDownHandler);
    });
});
#container {
      margin: 50px auto;
      border: 2px solid #ccc;
      border-radius: 10px;
      display: flex;
      width: 80%;
      gap: 1rem;
    }

    .item {
      border: 1px solid #cbd5e0;
      font-size: 2.25rem;
    }

    small {
      width: 150px;
      height: 150px;
      align-items: center;
      display: flex;
      justify-content: center;
    }
<html lang="en">

<head>
  <meta charset="utf-8" />
  <title>HTML DOM - Drag to scroll</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="stylesheet" href="/css/demo.css" />
  <link rel="preconnect" href="https://fonts.gstatic.com" />
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter&family=Source Code Pro&display=swap" />

</head>

<body>

  <div id="container" style=" overflow: auto; padding: 1rem">

    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>

  </div>


<div id="container" style=" overflow: auto; padding: 1rem">

    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>
    <div class="item"><small>12</small></div>

  </div>


</body>

</html>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

But you should change id to class since you shouldn't have duplicated ids in your DOM.

  • Related