解决 react h5移动端项目 fastclick点击多次才生效的问题

项目背景
react框架编写的移动端h5项目
项目中引用了fastclick.js
使用 input type=“file” 用户上传头像

faskclick实现原理
fastclick是通过在touchstart里记录触摸点信息,在touchend里判断此次触摸是否是个有效的click点击,如果是,则在touchend里阻止默认事件以防止产生原生click事件(因为会有 300ms 的延迟),并立即生成并触发自定义的click事件(没有延迟)

300ms产生的原理
时间要追溯到 2007 年初代 iPhone 发布前夕,苹果为了解决“如何用手机这种小尺寸屏幕来显示 PC 端网页”这个问题,提出了很多聪明的约定(convention)。而后因为 iPhone 的大获成功,这些约定被各大手机浏览器争相效仿。

这些约定之中,双击缩放(Double Tap to Zoom) 就是 300ms 的“元凶”——当用户在页面上 click 的时候,浏览器为了判断这个用户操作是单击还是双击,会等待 300-350ms 。如果 300ms 内,发生了第二次 click 事件,那么视为双击;否则为单击,等 300ms 时间过去之后,才触发 click 事件。

faskclick存在的问题
当我们项目中引用了fastclick.js插件的时候,很多点击场景是符合我们的需求的。但是有一些场景需要我们手动触发事件。
例如:当我们使用input标签做上传图片处理时,当我们点击input标签,就会调起选择拍照或选择照片的弹窗。

<input type="file" accept="image/*" onChange={handleChange} />
const handleChange = () => { // 处理我们选择完图片的逻辑 }

可以有些需求是不能在点input时调用起选择弹窗,而是先去做一些其他的逻辑,成功后再去选择图片或拍照。

const myRefInput = useRef(null); // 如果你项目支持hooks,如果不支持则用React.createRef()去创建 const myRefInput = React.createRef(null);
<div className="upload-head-pic" onClick={(e) => {handleClickDom(e)}}>
	<input type="file" accept="video/*;image/*" ref={myRefInput} style={{display: 'none'}} onChange={uploadHeadPic} />
<div/>

const handleClickDom = (e) => {
	console.log('点击', myRefInput.current);
	myRefInput.current.click(); // 这样点击是不会生效的
}

问题来了,这样点击不生效,只有多次点击才能生效。因为我们以js编程的形式去触发事件,不会触发touchstart事件,所以fastclick.js监听不到。fastclick多次点击才生效

解决办法
需要我们使用自定义事件来解决。

const handleClickDom = (e) => {
	const event = new MouseEvent('click');
    myRefInput.current.dispatchEvent(event);
}

生效原因:
通过new MouseEvent(‘click’)创建的事件,默认的event.cancelable和event.cancelBubble都为false,因此走到onMouse里会直接返回true,没有机会执行之后的needsClick以及阻止事件捕获的逻辑,会让事件进一步传播到input上,进而触发了input的click事件。

参考文献:https://www.jianshu.com/p/459102cd0ee9
https://bruceshang.github.io/2020/04/15/%E8%A7%A3%E5%86%B3vue%20fastclick%20$refs.file.click()%20%E9%9C%80%E8%A6%81%E7%82%B9%E5%87%BB%E5%A4%9A%E6%AC%A1%E6%89%8D%E7%94%9F%E6%95%88/

umi 是一个基于 react 的前端开发框架,它提供了一些方便的工具和规范,帮助我们更快地搭建和部署移动端 web 项目。而 antd design 是一个优秀的 UI 组件库,它提供了丰富的组件,能够满足我们在移动端 web 项目中的各种需求。 首先,我们可以使用 umi 来初始化一个移动端项目。umi 提供了脚手架工具,可以帮助我们快速创建一个基本的项目结构。通过命令行工具,我们可以选择使用 umi 内置的模板和插件,来搭建一个符合我们需求的移动端项目。 接着,我们可以使用 antd design 来构建我们的移动端页面。antd design 提供了丰富的 UI 组件,如导航栏、按钮、表单等等,这些组件都经过了精心设计和优化,可以帮助我们快速构建漂亮而且功能丰富的移动端页面。我们可以通过引入 antd design 的组件库,然后按照官方文档的指引使用这些组件,实现我们的页面功能。 在搭建项目时,umi 提供了一些功能和规范,例如路由配置、状态管理等。我们可以使用 umi 提供的路由功能来管理页面之间的跳转和传参,通过 umi 的状态管理功能可以更好地管理组件的状态和数据。同时,umi 还支持按需加载和自动优化等功能,能够提高项目的加载速度和性能。 总的来说,umi antd design react 搭建移动端 web 项目是一个很便捷和高效的选择。umi 提供了一个规范的开发框架,antd design 提供了丰富的 UI 组件,它们的结合可以帮助我们更快速地构建移动端 web 项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值