2

I have a horizontal scroll div that is also draggable. The elements which inside this div are links. every time I leave the drag it fire the click and send me to the link. Is there a way that I could prevent the click after leaving the drag but keep it available when not dragging?

here's a snippet:

const slider = document.querySelector('.wrapper');
let isDown = false;
let startX;
let scrollLeft;


slider.addEventListener('mousedown', (e) => {
    isDown = true;
    slider.classList.add('active');
    startX = e.pageX - slider.offsetLeft;
    scrollLeft = slider.scrollLeft;

});

slider.addEventListener('mouseleave', () => {
    isDown = false;
    slider.classList.remove('active');
});

slider.addEventListener('mouseup', () => {
    isDown = false;
    slider.classList.remove('active');
});

slider.addEventListener('mousemove', (e) => {
    if(!isDown) return;
    e.preventDefault();
    const x = e.pageX - slider.offsetLeft;
    const walk = (x - startX)*2;
    slider.scrollLeft = scrollLeft - walk;
});

document.getElementsByClassName('.book').ondragstart = function() { return false; };
.wrapper {
    position: relative;
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    overflow: auto;
    min-width: 100%;
}

.book {
    width: auto;
    height: 100vh;
    min-width: 50vw;
}

.one {
  background-color: #d07fe0;
  }
  
.two {
  background-color: #808888;
  }
  
.three {
  background-color: #83e7dc;
  }
  
.four {
  background-color: #edf7a8;
  }
  
.five {
  background-color: #e9d98f;
  }
  
.six {
  background-color: #fdd;
  }
  
<body>
<div class="wrapper">
    <a href="https://stackoverflow.com/" class="book one"></a>
    <a href="https://stackoverflow.com/" class="book two"></a>
    <a href="https://stackoverflow.com/" class="book three"></a>
    <a href="https://stackoverflow.com/" class="book four"></a>
    <a href="https://stackoverflow.com/" class="book five"></a>
    <a href="https://stackoverflow.com/" class="book six"></a>
</div>
</body>

I would appreciate any help. thanks! nir

nirshh5
  • 43
  • 1
  • 8

1 Answers1

4

One approach I can suggest .

Define a function preventClick

const preventClick = (e) => {
        e.preventDefault();
        e.stopImmediatePropagation();
      }

Define a variable isDragged to conditionally add and remove event listeners.

let isDragged = false;

On mouseup event, you enter with 2 cases, isDragged = false(in case of click) or isDragged = true (in case of drag)

First case: Remove the eventListener that prevents click propagation

Second case: Add the event listener that prevents click propagation.

Try the below code and let me know if this helps. Please note that this is not an optimized code. I'm adding and removing event handlers for all anchor tags just to demonstrate the approach you can follow.

const slider = document.querySelector(".wrapper");
      const preventClick = (e) => {
        e.preventDefault();
        e.stopImmediatePropagation();
      }
      let isDown = false;
      var isDragged = false;
      let startX;
      let scrollLeft;

      slider.addEventListener("mousedown", e => {
        isDown = true;
        slider.classList.add("active");
        startX = e.pageX - slider.offsetLeft;
        scrollLeft = slider.scrollLeft;
      });

      slider.addEventListener("mouseleave", () => {
        isDown = false;
        slider.classList.remove("active");
      });

      slider.addEventListener("mouseup", e => {
        isDown = false;
        const elements = document.getElementsByClassName("book");
        if(isDragged){
            for(let i = 0; i<elements.length; i++){
                  elements[i].addEventListener("click", preventClick);
            }
        }else{
            for(let i = 0; i<elements.length; i++){
                  elements[i].removeEventListener("click", preventClick);
            }
        }
        slider.classList.remove("active");
        isDragged = false;
      });

      slider.addEventListener("mousemove", e => {
        if (!isDown) return;
        isDragged =  true;
        e.preventDefault();
        const x = e.pageX - slider.offsetLeft;
        const walk = (x - startX) * 2;
        slider.scrollLeft = scrollLeft - walk;
      });

      document.getElementsByClassName("book").ondragstart = function() {
        console.log("Drag start");
      };
      .wrapper {
        position: relative;
        display: -webkit-box;
        display: -webkit-flex;
        display: -ms-flexbox;
        display: flex;
        overflow: auto;
        min-width: 100%;
      }

      .book {
        width: auto;
        height: 100vh;
        min-width: 50vw;
      }

      .one {
        background-color: #d07fe0;
      }

      .two {
        background-color: #808888;
      }

      .three {
        background-color: #83e7dc;
      }

      .four {
        background-color: #edf7a8;
      }

      .five {
        background-color: #e9d98f;
      }

      .six {
        background-color: #fdd;
      }
<body>
      <div class="wrapper">
        <a href="https://stackoverflow.com/" class="book one"></a>
        <a href="https://stackoverflow.com/" class="book two"></a>
        <a href="https://stackoverflow.com/" class="book three"></a>
        <a href="https://stackoverflow.com/" class="book four"></a>
        <a href="https://stackoverflow.com/" class="book five"></a>
        <a href="https://stackoverflow.com/" class="book six"></a>
      </div>
    </body>
Nithin Thampi
  • 3,579
  • 1
  • 13
  • 13