摘要:解決辦法解決辦法也很簡(jiǎn)單延遲事件的處理,直到判斷這個(gè)不在中。原理這個(gè)延遲的事件會(huì)放在一個(gè)隊(duì)列中,并處于狀態(tài)。當(dāng)事件觸發(fā)之后,就取消所有的這些事件也就不會(huì)執(zhí)行。
背景
上午樓主遇到一個(gè)需要處理雙擊事件的需求,在這里介紹下如何在觸發(fā)doubleCLick時(shí)間的時(shí)候, 不觸發(fā)click事件的解決辦法, 順便分享給大家。
問(wèn)題闡述首先, 我們的DOM 是天然支持dbClick 事件的, 線(xiàn)上demo:
https://codepen.io/scaukk/pen...
可以清晰的看到, 雙擊之后, 觸發(fā)處理雙擊事件的邏輯, 但是同時(shí)也觸發(fā)了兩次click事件:
這個(gè)副作用不是我們預(yù)期的, 需要處理一下。
解決辦法解決辦法也很簡(jiǎn)單: 延遲 click事件的處理, 直到判斷這個(gè)click 不在 doubleClick 中。
原理這個(gè)延遲的click事件會(huì)放在一個(gè) Promise 隊(duì)列中, 并處于pending狀態(tài)。
當(dāng)doubleClick事件觸發(fā)之后, 就取消所有的Pending Promises, 這些事件也就不會(huì)執(zhí)行。
可取消的Promise要處理這些處于 penging 狀態(tài)的Promise, 我們需要用到可取消的Promise, 這個(gè)話(huà)題我在另一片文章中討論過(guò), 有興趣的可以看一下。
下面是一個(gè)可以cancel的Promise的簡(jiǎn)單實(shí)現(xiàn):
export const cancellablePromise = promise => { let isCanceled = false; const wrappedPromise = new Promise((resolve, reject) => { promise.then( value => (isCanceled ? reject({ isCanceled, value }) : resolve(value)), error => reject({ isCanceled, error }), ); }); return { promise: wrappedPromise, cancel: () => (isCanceled = true), }; };
要解決開(kāi)頭提到的這個(gè)問(wèn)題, 我們就需要用到這個(gè)大殺器。
先看下最終的結(jié)果,雙擊一下:
主要代碼:
const EnhancedClickableBox = stopTriggerClicksOnDoubleClick(ClickableBox) const DoubleClickExample = () => (console.log("on click")} onDoubleClick={() => console.log("on double click")} /> ); const App = () => { return ( ) } ReactDOM.render( , document.getElementById("app"));
線(xiàn)上Demo:
https://codepen.io/scaukk/pen...
Hooks 版本const ClickableBox = ({ onClick, onDoubleClick }) => { const [handleClick, handleDoubleClick] = useClickPreventionOnDoubleClick(onClick, onDoubleClick); return ( ); }; const DoubleClickExample = () => (console.log("on click")} onDoubleClick={() => console.log("on double click")}/> ); const App = () => { return ( ) } ReactDOM.render( , document.getElementById("app"));
https://codepen.io/scaukk/pen...
是不是很簡(jiǎn)單, 學(xué)到了吧 XD
結(jié)語(yǔ)處理雙擊事件的時(shí)候, 最好還是處理掉不必要的click調(diào)用, 免得產(chǎn)生bug.
如果文章對(duì)你有幫助, 點(diǎn)個(gè)贊支持一下唄。
文中若有錯(cuò)誤,歡迎指出, 歡迎留言交流。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/116247.html
摘要:解決辦法解決辦法也很簡(jiǎn)單延遲事件的處理,直到判斷這個(gè)不在中。原理這個(gè)延遲的事件會(huì)放在一個(gè)隊(duì)列中,并處于狀態(tài)。當(dāng)事件觸發(fā)之后,就取消所有的這些事件也就不會(huì)執(zhí)行。 背景 上午樓主遇到一個(gè)需要處理雙擊事件的需求,在這里介紹下如何在觸發(fā)doubleCLick時(shí)間的時(shí)候, 不觸發(fā)click事件的解決辦法, 順便分享給大家。 問(wèn)題闡述 首先, 我們的DOM 是天然支持dbClick 事件的, 線(xiàn)上...
摘要:使用實(shí)現(xiàn)雙擊事件例如,這樣雙擊省略參數(shù)合法性的判斷自定義雙擊事件可以使用攜帶數(shù)據(jù)雙擊事件監(jiān)聽(tīng)雙擊事件觸發(fā)是否已經(jīng)點(diǎn)擊過(guò)一次事件分發(fā)使用數(shù)組實(shí)現(xiàn)雙擊事件或擊事件靈感來(lái)自于系統(tǒng)多擊觸發(fā)彩蛋的源碼用前端的方式實(shí)現(xiàn)長(zhǎng)這樣雙擊省略參數(shù)合法性的判斷創(chuàng)建 使用setTimeout實(shí)現(xiàn)雙擊事件 例如,這樣: let div = document.getElementById(div); doubleC...
摘要:使用實(shí)現(xiàn)雙擊事件例如,這樣雙擊省略參數(shù)合法性的判斷自定義雙擊事件可以使用攜帶數(shù)據(jù)雙擊事件監(jiān)聽(tīng)雙擊事件觸發(fā)是否已經(jīng)點(diǎn)擊過(guò)一次事件分發(fā)使用數(shù)組實(shí)現(xiàn)雙擊事件或擊事件靈感來(lái)自于系統(tǒng)多擊觸發(fā)彩蛋的源碼用前端的方式實(shí)現(xiàn)長(zhǎng)這樣雙擊省略參數(shù)合法性的判斷創(chuàng)建 使用setTimeout實(shí)現(xiàn)雙擊事件 例如,這樣: let div = document.getElementById(div); doubleC...
摘要:處理事件響應(yīng)是應(yīng)用中非常重要的一部分。中,處理事件響應(yīng)的方式有多種。關(guān)于事件響應(yīng)的回調(diào)函數(shù),還有一個(gè)地方需要注意。不管你在回調(diào)函數(shù)中有沒(méi)有顯式的聲明事件參數(shù),都會(huì)把事件作為參數(shù)傳遞給回調(diào)函數(shù),且參數(shù)的位置總是在其他自定義參數(shù)的后面。 React中定義一個(gè)組件,可以通過(guò)React.createClass或者ES6的class。本文討論的React組件是基于class定義的組件。采用cla...
摘要:假如我們從后臺(tái)拉取一個(gè)數(shù)據(jù)要填入輸入框,那么必須得使用受控組件,因?yàn)榉鞘芸亟M件只能被用戶(hù)輸入。不影響正常輸入填充該輸入框的默認(rèn)值,此時(shí)不顯示內(nèi)容。 網(wǎng)頁(yè)中使用的form表單大家肯定都再熟悉不過(guò)了,它主要作用是用來(lái)收集和提交信息。React中的表單組件與我們普通的Html中的表單及其表現(xiàn)形式?jīng)]有什么不同,所以如何使用表單我覺(jué)得再拿出來(lái)說(shuō)可能是畫(huà)蛇添足、毫無(wú)意義。不過(guò)再怎么樣也不能辜負(fù)大家...
閱讀 3940·2021-09-10 11:22
閱讀 2444·2021-09-03 10:30
閱讀 3732·2019-08-30 15:55
閱讀 2053·2019-08-30 15:44
閱讀 904·2019-08-30 15:44
閱讀 646·2019-08-30 14:04
閱讀 3125·2019-08-29 17:18
閱讀 1336·2019-08-29 15:04