React?事件綁定的最佳實踐
事件綁定
移動端的click會存在300ms延遲,移動端的click是點擊事件,PC端的click是點擊。
比如連著點擊兩下:
- PC會觸發(fā):兩次click、一次dbclick
- 移動端:不回觸發(fā)click、只會觸發(fā)dbclick
點擊事件:第一次點擊后,檢測300ms,看看會不會有第二次點擊操作,如果沒有事單擊,如果有就是雙擊。
render() { return <div> <button onTouchStart={this.touchstart} onTouchMove={this.touchmove} onTouchEnd={this.touchend}> 提交 </button> </div>; }
解決方案一:單手指事件模型
在觸摸屏設(shè)備上,單手指事件模型主要通過 touch 相關(guān)的事件來處理。以下是常見的觸摸事件:
touchstart:當(dāng)手指觸摸屏幕時觸發(fā)??梢杂脕碛涗浻|摸的開始位置。
touchmove:手指在屏幕上滑動時觸發(fā)。可以用來追蹤手指的移動位置。
touchend:手指從屏幕上離開時觸發(fā)??梢杂脕硖幚碛|摸結(jié)束后的邏輯。
touchcancel:當(dāng)觸摸事件被系統(tǒng)打斷時觸發(fā),例如,設(shè)備出現(xiàn)電話、通知等中斷時。
模擬點擊效果,可以監(jiān)聽 touchstart 和 touchend 事件。通過判斷觸摸的起始位置和結(jié)束位置,確定是否是點擊操作。如果在一定時間內(nèi)沒有滑動,并且觸摸的起始和結(jié)束位置幾乎相同,則可以認(rèn)為是一個點擊。
class Demo extends React.Component { // 手指按下:記錄手指的起始坐標(biāo) touchstart = (ev) => { console.log('startstartstartstartstart') let finger = ev.changedTouches[0]; //記錄了操作手指的相關(guān)信息 this.touchStartTime = Date.now(); this.touch = { startX: finger.pageX, startY: finger.pageY, isMove: false }; }; // 手指移動:記錄手指偏移值,和誤差值做對比,分析出是否發(fā)生移動 touchmove = (ev) => { console.log('movemovemovemove') let finger = ev.changedTouches[0], { startX, startY } = this.touch; let changeX = finger.pageX - startX, changeY = finger.pageY - startY; if (Math.abs(changeX) > 10 || Math.abs(changeY) > 10) { this.touch.isMove = true; } }; // 手指離開:根據(jù)isMove判斷是否是點擊 touchend = () => { console.log('endddddd') this.touchEndTime = Date.now(); console.log(this.touch.isMove, 'this.touch.isMove') // 點擊操作時間是否小于300ms if (this.touchEndTime - this.touchStartTime < 300) { this.touch.isMove = false; } let { isMove } = this.touch; if (isMove) return; // 說明觸發(fā)了點擊操作 console.log('點擊了按鈕'); }; }
解決方案二:fastclick(已過時,仍可用)
使用fastclick
插件解決移動端使用click事件的300ms延遲問題,在入口文件導(dǎo)入。注意:可能與其他庫或框架沖突
import FastClick from "fastclick" FastClick.attach(document.body)
handle = ()=>{ .... } render() { return <div> <button onClick={this.handle}> 提交 </button> </div>; }
解決方案三:CSS touch-action屬性
touch-action
屬性允許開發(fā)者控制瀏覽器對觸摸手勢的默認(rèn)行為。 將 touch-action
設(shè)置為none
可以阻止瀏覽器對觸摸事件的默認(rèn)處理,包括雙擊縮放,從而消除 300ms 延遲。
循環(huán)事件綁定
在React中,我們給循環(huán)「創(chuàng)建」的元素做“循環(huán)事件綁定”,是好還是不好?按常理來說,此類需求用事件委托處理是最好的,但是在React 中,我們循環(huán)給元素綁定的合成事件本身就是基于事件委托處理的
,所以無需我們自己再單獨的設(shè)置事件委托的處理機制
class Demo extends React.Component { state = { arr: [{ id: 1, title: '新聞' }, { id: 2, title: '體育' }, { id: 3, title: '電影' }] }; handle = (item) => { // item:點擊這一項的數(shù)據(jù) console.log('我點擊的是:' + item.title); }; render() { let { arr } = this.state; return <div> {arr.map(item => { let { id, title } = item; return <span key={id} style={{ padding: '5px 15px', marginRight: 10, border: '1px solid #DDD', cursor: 'pointer' }} onClick={this.handle.bind(this, item)}> {title} </span>; })} </div>; } }
在vue中,給當(dāng)前元素添加事件綁定就是給給它做事件綁定,我們可以給它父級元素做事件委托
,根據(jù)事件源判斷點擊的是哪一個
<template> <div class="list-container" @click="handleClick"> <div class="item" v-for="(item, index) in items" :key="index"> {{ item }} </div> </div> </template> <script> export default { data() { return { items: ['Item 1', 'Item 2', 'Item 3', 'Item 4'] }; }, methods: { handleClick(event) { // 獲取事件源 const clickedElement = event.target; // 判斷點擊的是哪個子元素(例如列表項) if (clickedElement && clickedElement.classList.contains('item')) { // 獲取點擊的列表項的文本內(nèi)容 const clickedItem = clickedElement.textContent; console.log(`點擊了: ${clickedItem}`); } } } } </script>
到此這篇關(guān)于React 事件綁定的最佳實踐的文章就介紹到這了,更多相關(guān)React 事件綁定內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React不使用requestIdleCallback實現(xiàn)調(diào)度原理解析
這篇文章主要為大家介紹了React不使用requestIdleCallback實現(xiàn)調(diào)度原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11react-redux多個組件數(shù)據(jù)共享的方法
這篇文章主要介紹了react-redux多個組件數(shù)據(jù)共享的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08react路由基礎(chǔ)解讀(Router、Link和Route)
這篇文章主要介紹了react路由基礎(chǔ)解讀(Router、Link和Route),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07