7

I have created a horizontal projects gallery. I want to let the visitor drag right & left to scroll.

This is my pen: https://codepen.io/omritk1/pen/qBByEoR. My problem is that after the scroll, on "mouseup", it triggers click on the link. How can I prevent this event but also let the user click on the link.

(I have used this pen as to set the JS: https://codepen.io/toddwebdev/pen/yExKoj)

const slider = document.querySelector('.catalog-list');
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) * 1;
  slider.scrollLeft = scrollLeft - walk;
  console.log(walk);
});
.projects-catalog .catalog-slider {
    margin: 50px 0px;
}
.projects-catalog .catalog-cover {
    position: relative;
}
.projects-catalog ul {
    white-space: nowrap;
    overflow-x: auto;
}
.projects-catalog li {
    width: 75%;
    height: 200px;
}
li.catalog-item {
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}
.projects-catalog li {
    display: inline-block;
    margin: 0 10px 0 0;
    width: 350px;
    height: 250px;
    background: #222;
}
<div class="projects-catalog">
  <div id="imageSlider1" class="catalog-slider">
    <div class="catalog-cover">
      <ul id="sliderWrapper1" class="catalog-list corporate-projects">
        <i id="prev1" class="fas fa-chevron-left move-left" style="display: flex;"></i>
        <a href="https://codepen.io/">
              <li class="catalog-item"></li>
          </a>
          <a href="https://codepen.io/">
              <li class="catalog-item"></li>
          </a>
          <a href="https://codepen.io/">
              <li class="catalog-item"></li>
          </a>
          <a href="https://codepen.io/">
              <li class="catalog-item"></li>
          </a>
          <a href="https://codepen.io/">
              <li class="catalog-item"></li>
          </a>
          <a href="https://codepen.io/">
              <li class="catalog-item"></li>
          </a>
          <a href="https://codepen.io/">
              <li class="catalog-item"></li>
          </a>
          <a href="https://codepen.io/">
                <li class="catalog-item"></li>
          </a>
          <a href="https://codepen.io/">
              <li class="catalog-item"></li>
          </a>
          <a href="https://codepen.io/">
              <li class="catalog-item"></li>
          </a>
        <i id="next1" class="fas fa-chevron-right move-right"></i>
      </ul>
    </div>
  </div>
</div>

2 Answers 2

10

Looks like a duplicate of this .

Try the below snippet.

      const slider = document.querySelector(".catalog-list");
      const preventClick = (e) => {
        e.preventDefault();
        e.stopImmediatePropagation();
      }
      let isDown = false;
      let 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.querySelectorAll("a");
        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;
        console.log(walk);
      });
.projects-catalog .catalog-slider {
  margin: 50px 0px;
}

.projects-catalog .catalog-cover {
  position: relative;
}

.projects-catalog ul {
  white-space: nowrap;
  overflow-x: auto;
}

.projects-catalog li {
  width: 75%;
  height: 200px;
}

li.catalog-item {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.projects-catalog li {
  display: inline-block;
  margin: 0 10px 0 0;
  width: 350px;
  height: 250px;
  background: #222;
}
<div class="projects-catalog">
  <div id="imageSlider1" class="catalog-slider">
    <div class="catalog-cover">
      <ul id="sliderWrapper1" class="catalog-list corporate-projects">
        <i id="prev1" class="fas fa-chevron-left move-left" style="display: flex;"></i>
        <a href="https://codepen.io/">
          <li class="catalog-item"></li>
        </a>
        <a href="https://codepen.io/">
          <li class="catalog-item"></li>
        </a>
        <a href="https://codepen.io/">
          <li class="catalog-item"></li>
        </a>
        <a href="https://codepen.io/">
          <li class="catalog-item"></li>
        </a>
        <a href="https://codepen.io/">
          <li class="catalog-item"></li>
        </a>
        <a href="https://codepen.io/">
          <li class="catalog-item"></li>
        </a>
        <a href="https://codepen.io/">
          <li class="catalog-item"></li>
        </a>
        <a href="https://codepen.io/">
          <li class="catalog-item"></li>
        </a>
        <a href="https://codepen.io/">
          <li class="catalog-item"></li>
        </a>
        <a href="https://codepen.io/">
          <li class="catalog-item"></li>
        </a>
        <i id="next1" class="fas fa-chevron-right move-right"></i>
      </ul>
    </div>
  </div>
</div>

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

1 Comment

Hi, I've created another two sliders like this on the same page. Do you have any idea how can I make it work for all of them? Thanks!
-1

Add this to your CSS file

.active .catalog-item {
  pointer-events: none;
}

EDIT: Credits: https://stackoverflow.com/a/24273710/5757893

EDIT: Then remove the following line from mousedown event

slider.classList.add('active');

And add it to the mousemove event method as follows:

if (Math.abs(startX - e.pageX) > 10) {
  slider.classList.add('active');
}

So that if you start dragging at least 10 pixels it won't register pointer events, but if you didn't move too much, it'll stay click the link.

2 Comments

Its disable the ability to click on the link... I need to click after drag.
Disabling pointer events disables all ability to interact with the scrolling content... defeats the entire purpose.

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.