Skip to content
Advertisement

javascript stop click event on mousemove

i have a draggable parent with click events on the children. i want to cancel/abort/stop the click event of the child when it’s starting to get dragged, but also don’t want do stop any parent events. Since i don’t use a lot of jQuery, i’d be very thankful for a vanilla javascript solution.

sorry for this newbie question, but i can’t wrap my head around it.

here is what i got so far: JSFiddle

// horizontal drag scroll for items
const itemScroll = document.querySelector('#itemScroll');
var isDown = false;
var startX;
var scrollLeft;

itemScroll.addEventListener('mousedown', (e) => {
  isDown = true;
  itemScroll.classList.add('active');
  startX = e.pageX - itemScroll.offsetLeft;
  scrollLeft = itemScroll.scrollLeft;
});
itemScroll.addEventListener('mouseleave', () => {
  isDown = false;
  itemScroll.classList.remove('active');
});
itemScroll.addEventListener('mouseup', () => {
  isDown = false;
  itemScroll.classList.remove('active');
});
itemScroll.addEventListener('mousemove', (e) => {
  if (!isDown) return;
  e.preventDefault();
  const x = e.pageX - itemScroll.offsetLeft;
  itemScroll.scrollLeft = scrollLeft - (x - startX);
});

// click an item to change bg-color
const items = document.querySelectorAll('.item');

for (var i = 0; i < items.length; i++) {
  items[i].addEventListener('click', function (e) {
    this.classList.toggle('active');
  });
}

Advertisement

Answer

Detect movement and in that case “prevent” the default click behaviour programmatically using a global variable. We reset the is_moved variable when mousedown, and set it when mousemove.

// horizontal drag scroll for items
const itemScroll = document.querySelector('#itemScroll');
var isDown = false;
var startX;
var scrollLeft;
var isMoved = false;

itemScroll.addEventListener('mousedown', (e) => {
  isDown = true;
  isMoved = false;
  itemScroll.classList.add('active');
  startX = e.pageX - itemScroll.offsetLeft;
  scrollLeft = itemScroll.scrollLeft;
});
itemScroll.addEventListener('mouseleave', () => {
  isDown = false;
  itemScroll.classList.remove('active');
});
itemScroll.addEventListener('mouseup', () => {
  isDown = false;
  itemScroll.classList.remove('active');
});
itemScroll.addEventListener('mousemove', (e) => {
  if (!isDown) return;
  isMoved = true;
  e.preventDefault();
  const x = e.pageX - itemScroll.offsetLeft;
  itemScroll.scrollLeft = scrollLeft - (x - startX);
});

// click an item to change bg-color
const items = document.querySelectorAll('.item');

for (var i = 0; i < items.length; i++) {
  items[i].addEventListener('click', function(e) {
    if (!isMoved) {
      this.classList.toggle('active');
    }
  });
}
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.mainCont {
  width: 100%;
  max-width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  scroll-snap-align: center;
}

#itemScroll {
  cursor: pointer;
  overflow-x: hidden;
}

#itemScroll.active {
  cursor: grabbing;
}

.itemRow {
  width: max-content;
  min-width: 100%;
  height: 100%;
  max-height: 400px;
  padding: 0 5vw;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 5rem;
  transform-style: preserve-3d;
}

.item {
  width: 100px;
  height: 100px;
  max-width: 400px;
  max-height: 100%;
  background-color: red;
}

.item.active {
  background-color: green;
}
<div class="mainCont" id="itemScroll">
  <div class="itemRow">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
</div>
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement