Remove Event Listeners that need to Receive Multiple Arguments JS

I built a tab that a user can close using touch events and when the tab closes I want to be able to remove event listeners. This is a little bit tricky because in my actual code there is a modal and there is a part in that dynamically inserted content that the touch events are attached to.

So if i have the below code

const tab = document.querySelector('.tab')

function handleMove(e, tab) {
  e.preventDefault()
  tab.style....
}

// I add the event listener like this
// but then I can't remove it
tab.addEventListener('touchmove', e => {
  handleMove(e, tab)
})

Below is more realistic with what I am dealing with.

const swipeTab = document.querySelector('.swipeable-tab')

let y1, timeStart, timeEnd

function closeStart(e) {
  e.preventDefault()
  let touchLocation = e.targetTouches[0]
  y1 = touchLocation.clientY
  console.log({ y1 })
  timeStart = e.timeStamp
}


function closeMove(e, swipeTab) {
  e.preventDefault()
  swipeTab.style.transform = ''
  let touchLocation = e.touches[0]
  let yLocation = touchLocation.clientY

  if (yLocation > swipeTab.clientHeight + y1) {
    yLocation = swipeTab.clientHeight + y1
  }

  swipeTab.style.transition = ''
  let marker = yLocation - y1
  console.log({ marker })

  if (marker < 0) {
    marker = 0
  }
  
  swipeTab.style.transform = `translate3d(0, ${marker}px, 0)`
}



function closeEnd(e, swipeTab) {
  e.preventDefault()
  let touchLocation = e.changedTouches[0]; 
  let y2 = touchLocation.clientY; 
  let yDiff = y2 - y1; 
  console.log({ yDiff })
  timeEnd = e.timeStamp; 
  timeDiff = timeEnd - timeStart; 
  console.log({ y2 })
  console.log({ timeDiff })

  if (yDiff > swipeTab.clientHeight/3 || timeDiff < 50) {
    closeTab(swipeTab)
  } else {
    openTab(swipeTab)
  }

}


function openTab(swipeTab) {
  swipeTab.style.transition = `all 0.2s ease-in-out`
  swipeTab.style.transform = `translate3d(0, 0%, 0)`
  addCloseEventListeners(swipeTab)
}

/**
 * I am trying to come up with something similar to this
*/

function closeTab(swipeTab) {
  swipeTab.style.transition = `all 0.2s ease-in-out`
  swipeTab.style.transform = `translate3d(0, 100%, 0)`
  removeCloseEventListeners(tab)
}

function removeCloseEventListeners(swipeTab) {
  swipeTab.removeEventListener('touchstart', closeStart); 
  swipeTab.removeEventListener('touchmove', closeMove); 
  swipeTab.removeEventListener('touchend', closeEnd); 
}


/**
 * when open(swipeTab) is called
 * then the event listeners are added for closing the tab
*/
function addCloseEventListeners(swipeTab) {

  swipeTab.addEventListener('touchstart', e => {
    closeStart(e)
  }) 

  swipeTab.addEventListener('touchmove', e => {
    closeMove(e, swipeTab)
  })

  swipeTab.addEventListener('touchend', e => {
    closeEnd(e, swipeTab)
  })
 }


/**
 * this is where it starts
*/
open(swipeTab)

>Solution :

Make more variables.

function removeCloseEventListeners(swipeTab) {
  swipeTab.removeEventListener("touchstart", swipeTouchStart);
  swipeTab.removeEventListener("touchmove", swipeTouchMove);
  swipeTab.removeEventListener("touchend", swipeTouchEnd);
}

const swipeTouchStart = (e) => closeStart(e);
const swipeTouchMove = (e) => closeMove(e, swipeTab);
const swipeTouchEnd = (e) => closeEnd(e, swipeTab);

function addCloseEventListeners(swipeTab) {
  swipeTab.addEventListener("touchstart", swipeTouchStart);
  swipeTab.addEventListener("touchmove", swipeTouchMove);
  swipeTab.addEventListener("touchend", swipeTouchEnd);
}

Also, you don’t need to make your functions take swipeTab as a parameter:

function addCloseEventListeners() {

since swipeTab is already a global variable in the script.

Leave a Reply