skip to Main Content

I’m trying to stop click events if dragged.

I think the simplest version of this is dragging yourself. Basically IF the user presses down, then moves, then releases I don’t want a click event.
this is the script

const tabsBox = document.querySelector('.kemem'),
  allTabs = tabsBox.querySelectorAll('.pop-post'),
  arrowIcons = document.querySelectorAll('.icon-mem svg')

let isDragging = false

const handleIcons = scrollVal => {
  let maxScrollableWidth = tabsBox.scrollWidth - tabsBox.clientWidth
  arrowIcons[0].parentElement.style.display = scrollVal <= 0 ? 'none' : 'flex'
  arrowIcons[1].parentElement.style.display =
    maxScrollableWidth - scrollVal <= 1 ? 'none' : 'flex'
}

arrowIcons.forEach(icon => {
  icon.addEventListener('click', () => {
    // if clicked icon is left, reduce 350 from tabsBox scrollLeft else add
    let scrollWidth = (tabsBox.scrollLeft += icon.id === 'left' ? -340 : 340)
    handleIcons(scrollWidth)
  })
})

allTabs.forEach(tab => {
  tab.addEventListener('click', () => {
  e.preventDefault();
  e.stopPropagation();
    tabsBox.querySelector('.active').classList.remove('active')
    tab.classList.add('active')
  })
})

const dragging = e => {
  e.preventDefault();
  e.stopPropagation();
  if (!isDragging) return
  tabsBox.classList.add('dragging')
  tabsBox.scrollLeft -= e.movementX
  handleIcons(tabsBox.scrollLeft)
}

const dragStop = () => {
  isDragging = false
  e.preventDefault();
  e.stopPropagation();
  tabsBox.classList.remove('dragging')
}

tabsBox.addEventListener('mousedown', () => (isDragging = true))
tabsBox.addEventListener('mousemove', dragging)
document.addEventListener('mouseup', dragStop)
    <div class='icon-mem lefto'><div class='overflow-left'></div><svg aria-hidden='true' class='jt-icon' id='left'><use xlink:href='#i-arrow-l'></use></svg></div>
      <ul class="kemem">
        <li class="pop-list">Programming</li>
        <li class="pop-list">HTML</li>
        <li class="pop-list">CSS</li>
        <li class="pop-list">Python</li>
      </ul>
    <div class='icon-mem righto'><div class='overflow-right'></div><svg aria-hidden='true' class='jt-icon' id='right'><use xlink:href='#i-arrow-r'></use></svg></div>

this is the demo : demo

Am I missing a simpler solution?

2

Answers


  1. You can add and remove a click event that prevents other click events from happening when you stop dragging.

    function preventClick(e){
      e.preventDefault();
      e.stopImmediatePropagation();
    }
    
    const dragStop = (e) => {
      if(isDragging) e.target.addEventListener("click", preventClick);
      else e.target.removeEventListener("click", preventClick)
      isDragging = false
      e.preventDefault();
      e.stopPropagation();
      tabsBox.classList.remove('dragging')
    }
    
    Login or Signup to reply.
  2. You only need to record the initial and the ending state of the ‘pointer’. Attach a property on the element (_initX) and compare that during ‘click’ event. If sufficiently close (within epsilon range), then fire the event otherwise suppress. One thing that kept my attention is that, if I substitued ‘click’ with ‘pointerup’, I was not able to suppress the behavior on the link in some browsers. ‘click’ seems to get the job done both in mobile and web browser.

    const a = document.getElementsByTagName("A")[0],
          epsilon = 10e-1;
    a.addEventListener("pointerdown", function(e){
      a._initX = e.clientX; //record the position
    })
    document.documentElement.addEventListener("pointermove", function(e){
      e.preventDefault(); //many browsers will cancel opening links if dragged, so suppress that :)
    })
    a.addEventListener("click", function(e){
      if (isNaN(a._initX)){return}
      if (
        e.clientX > a._initX - epsilon &&
        e.clientX < a._initX + epsilon
      ) {/*No drag, so links will fire*/} else {
        //drag detected, suppress the link
        e.stopImmediatePropagation();
        e.preventDefault();
      }
      a._initX = NaN;
    })
    a {
      display: block;
      background: Gray;
      border-radius: 2px solid gray;
      width: 200px;
      height: 200px;
      display: flex;
      align-items: center;
      justify-content: center;
      text-decoration: none;
    }
    <a href="https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events" target="_blank">LINK</a>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search