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. 這有點棘手,因為在我的實際代碼中有一個模式,并且在動態插入的內容中有一部分是觸摸事件附加到的。
所以如果我有下面的代碼
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)
})
下面是我正在處理的更現實的情況。
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)
uj5u.com熱心網友回復:
做更多的變數。
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);
}
此外,您不需要將函式swipeTab作為引數:
function addCloseEventListeners() {
因為swipeTab已經是腳本中的全域變數。
uj5u.com熱心網友回復:
我可能會創建一個輔助函式,該函式添加一個偵聽器并回傳一個回呼,其中removeEventListener()包含與添加時相同的簽名。然后,您可以存盤這些回呼以在removeCloseEventListeners()函式中使用,這里使用全域陣列并在使用后將其長度設定為 0。
這將使用作為引數傳遞的每個事件swipeTab以及事件將附加到的元素重新宣告回呼。它還避免了當前代碼中的重復,允許您一次性定義事件,addCloseEventListeners()而無需在關閉函式中添加/編輯它們。
function addEventListenerWithAnonymousCallback(element, event, cb, options = {}) {
element.addEventListener(event, cb, options);
return () => element.removeEventListener(event, cb, options);
}
const closeListeners = [];
function removeCloseEventListeners() {
for (const removeListener of closeListeners) {
removeListener();
}
closeListeners.length = 0;
}
function addCloseEventListeners(swipeTab) {
const listeners = [
["touchstart", (e) => closeStart(e)]
["touchmove", (e) => closeMove(e, swipeTab)],
["touchend", (e) => closeEnd(e, swipeTab)],
];
for (const [event, cb] of listeners) {
const removeListener = addEventListenerWithAnonymousCallback(swipeTab, event, cb);
closeListeners.push(removeListener);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/528976.html
標籤:javascript
