事件绑定
移动端的click会存在300ms延迟,移动端的click是点击事件,PC端的click是点击。
比如连着点击两下:
- PC会触发:两次click、一次dbclick
- 移动端:不回触发click、只会触发dbclick
点击事件:第一次点击后,检测300ms,看看会不会有第二次点击操作,如果没有事单击,如果有就是双击。
render() { return <div> <button onTouchStart={this.touchstart} onTouchMove={this.touchmove} onTouchEnd={this.touchend}> 提交 </button> </div>; }
解决方案一:单手指事件模型
在触摸屏设备上,单手指事件模型主要通过 touch 相关的事件来处理。以下是常见的触摸事件:
-
touchstart:当手指触摸屏幕时触发。可以用来记录触摸的开始位置。
-
touchmove:手指在屏幕上滑动时触发。可以用来追踪手指的移动位置。
-
touchend:手指从屏幕上离开时触发。可以用来处理触摸结束后的逻辑。
-
touchcancel:当触摸事件被系统打断时触发,例如,设备出现电话、通知等中断时。
模拟点击效果,可以监听 touchstart 和 touchend 事件。通过判断触摸的起始位置和结束位置,确定是否是点击操作。如果在一定时间内没有滑动,并且触摸的起始和结束位置几乎相同,则可以认为是一个点击。
class Demo extends React.Component { // 手指按下:记录手指的起始坐标 touchstart = (ev) => { console.log('startstartstartstartstart') let finger = ev.changedTouches[0]; //记录了操作手指的相关信息 this.touchStartTime = Date.now(); this.touch = { startX: finger.pageX, startY: finger.pageY, isMove: false }; }; // 手指移动:记录手指偏移值,和误差值做对比,分析出是否发生移动 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; } }; // 手指离开:根据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; // 说明触发了点击操作 console.log('点击了按钮'); }; }
解决方案二:fastclick(已过时,仍可用)
使用fastclick
插件解决移动端使用click事件的300ms延迟问题,在入口文件导入。注意:可能与其他库或框架冲突
import FastClick from "fastclick" FastClick.attach(document.body)
handle = ()=>{ .... } render() { return <div> <button onClick={this.handle}> 提交 </button> </div>; }
解决方案三:CSS touch-action属性
touch-action
属性允许开发者控制浏览器对触摸手势的默认行为。 将 touch-action
设置为none
可以阻止浏览器对触摸事件的默认处理,包括双击缩放,从而消除 300ms 延迟。
循环事件绑定
在React中,我们给循环「创建」的元素做“循环事件绑定”,是好还是不好?按常理来说,此类需求用事件委托处理是最好的,但是在React 中,我们循环给元素绑定的合成事件本身就是基于事件委托处理的
,所以无需我们自己再单独的设置事件委托的处理机制
class Demo extends React.Component { state = { arr: [{ id: 1, title: '新闻' }, { id: 2, title: '体育' }, { id: 3, title: '电影' }] }; handle = (item) => { // item:点击这一项的数据 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中,给当前元素添加事件绑定就是给给它做事件绑定,我们可以给它父级元素做事件委托
,根据事件源判断点击的是哪一个
<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')) { // 获取点击的列表项的文本内容 const clickedItem = clickedElement.textContent; console.log(`点击了: ${clickedItem}`); } } } } </script>
到此这篇关于React 事件绑定的最佳实践的文章就介绍到这了,更多相关React 事件绑定内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源链接:https://www.jb51.net/javascript/338155dvh.htm
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
暂无评论内容