当前位置: 首页 > news >正文

记录H5内嵌到flutter App的一个问题,引发后面使用fastClick,引发后面input输入框单击无效问题。。。

文章目录

    • 概要
    • 发现问题
    • 排查问题
    • FastClick 解决问题
    • FastClick 引发问题
    • 小结

概要

最近开发遇到一个很奇怪的问题,很特殊,为此记录一下
场景:H5单页面内嵌到App端
双方技术栈:H5 是 vue3 + vite / App 是flutter

发现问题

再一次开发的时候,ui检查样式是,发现页面无法点击了,必须重新进入才能点击,只有进入后的最开始点击的那一次生效,之后整个页面的点击事件都不生效


开始我保持怀疑的态度,因为我用了公司的安卓测试机,苹果测试机都没有问题,后来我用我自己的手机,突然发现,上诉问题复现了。。。

再经过我仔细来回测试,我发现只有IOS 18以上的系统才会出现这种问题,我公司的苹果测试机系统是16的

排查问题

  • 怀疑布局的问题
    为什么会有这个怀疑呢,因为当时我这个页面用了fixed以及absolute布局,大家都知道最开始的时候苹果对定位一直不是很友好的,为此我特意写了个demo,没有使用任何定位,但是其他的和我开发的内容一模一样,发现还是存在上述问题

  • 怀疑vue3的问题
    为什么这么说呢,是因为开始我问我的同事是否遇到过,都说没有,他们之前也开发过这种H5内嵌App的业务需求,但是他们用的是vue2的技术栈,为此我特意写了个vue2 和 vue3的demo,除了写法不一样,其他的是一模一样,结果发现都会出现上述问题

  • 怀疑App问题
    为什么会怀疑App的问题呢,因为我反复测试,发现最开始click点击事件都是好的,只有当点击调用App里面flutter方法后,唤起弹框后,我整个页面的click事件都失效了,怀疑是不是调用完他们的方法后,是不是有一层看不到的蒙版挡住了,但是App反馈说没有,并且说如果有蒙版那么不应该能滑动,事实是可以滑动,只是点击失效了

FastClick 解决问题

排查了半天,其实问题是知道了,但是解决呢,就比较恶心了,为什么呢,App说那没问题,所以App不解决,本来想说是App环境问题,但是老板用进入这个页面发现点击不了,肯定会找H5啊,因为页面内容是H5开发的,没办法只能想办法解决了

  • click失效,那尝试使用dblclick/touchstart 事件代替
    发现这两个事件都没问题,但是点击很麻烦或者误触,实际效果太不好了,但这两个事件都生效给我带来了新的思路
  • FastClick 包
    FastClick最原本的目的是用于解决移动设备上触摸事件延迟的 JavaScript 库,主要功能是消除这种 300 毫秒的延迟。其实现原理主要包括以下几个步骤
    1,监听触摸事件:
    FastClick 主要通过监听 touchstart 和 touchend 事件来处理用户的触摸行为。它会在touchstart 事件触发时记录时间戳和触摸目标。
    2,计算时间差:
    当 touchend 事件触发时,FastClick 会比较 touchstart 事件和 touchend 事件的时间差。如果时间差小于一定阈值(通常是 250 毫秒),且目标元素是可点击的(例如,按钮或链接),则 FastClick 会立即触发 click 事件,而不需要等待 300 毫秒。
    3,模拟 click 事件:
    在触摸结束时,如果触发条件符合,FastClick 会手动触发一个 click 事件,确保用户能够立即看到点击效果。它通过 document.createEvent 和 dispatchEvent 创建并分发 click 事件。
    4,处理移动端的特殊情况:
    FastClick 还处理了一些特定的移动端情况,例如:
    阻止默认的 click 事件,确保 FastClick 触发的事件可以在不产生延迟的情况下执行。
    确保只在可点击的元素上应用 FastClick,从而不会影响其他元素的默认行为。

可以简单的理解成一下内容,模拟简写FastClick伪代码示例

function FastClick(layer) {this.layer = layer;this.trackingClick = false;this.trackingClickStart = 0;this.targetElement = null;// 绑定事件layer.addEventListener('touchstart', this.onTouchStart.bind(this), false);layer.addEventListener('touchend', this.onTouchEnd.bind(this), false);layer.addEventListener('click', this.onClick.bind(this), false);
}FastClick.prototype.onTouchStart = function(event) {this.trackingClick = true;this.trackingClickStart = Date.now();this.targetElement = event.target; // 记录目标元素
};FastClick.prototype.onTouchEnd = function(event) {if (!this.trackingClick) return;var target = this.targetElement;var timeDiff = Date.now() - this.trackingClickStart;if (timeDiff < 250) { // 阈值判断// 手动触发 click 事件var clickEvent = new MouseEvent('click', { bubbles: true, cancelable: true });target.dispatchEvent(clickEvent);}this.trackingClick = false; // 重置状态
};FastClick.prototype.onClick = function(event) {// 阻止默认 click 事件if (this.trackingClick) {event.preventDefault();}
};// 初始化 FastClick
var layer = document.body; // 或者其他需要绑定的元素
new FastClick(layer);

FastClick 底层用的正好是touchstart和touchend重写了click事件,正好我上述的问题,只有click失效,其他事件例如touchstart是没问题的

FastClick 引发问题

正当我使用FastClick后,发现完美解决了这个问题,感到十分开心的时候,引发了另一个问题,那就是ios系统输入框需要长按/双击才能输入的问题

直接说解决吧

import FastClick from 'fastclick'const rewriteFocus = (targetElement) => {let length = null// Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.if (deviceIsIOS &&targetElement.setSelectionRange &&targetElement.type.indexOf('date') !== 0 &&targetElement.type !== 'time' &&targetElement.type !== 'month') {length = targetElement.value.lengthtargetElement.focus()targetElement.setSelectionRange(length, length)} else {targetElement.focus()}
}FastClick.attach(document.body)
FastClick.prototype.focus = rewriteFocus

以上方法也是参考以下博客的内容,其实就是重写下focus方法,这里推荐两篇博客,我也是借鉴而来

vue引入fastClick导致的输入框点击无响应问题

解决因引入了fastclick导致的ios系统输入框需要长按/双击才能输入的问题

小结

最后,我只想说累死了,这个问题,太恶心了,记录一下吧,希望对大家有点作用

http://www.dtcms.com/a/263287.html

相关文章:

  • BI软件选型:7款可私有部署产品对比
  • 利用不坑盒子的Copilot,快速排值班表
  • 在 Vue3 + Element Plus 中实现 el-table 拖拽排序功能
  • 【c语言课程设计】单选题考试系统(无链表,含码源)
  • 多校区在线跑腿小程序源码系统搭建平台 PHP+MySQL组合开发 含完整的搭建教程
  • 商品中心—16.库存分桶调配的技术文档
  • 【分布式】自定义统一状态机流转设计
  • Flowable01SpringBoot项目的引入--------------------每天都会更新,自学中
  • 组成原理精讲课--硬布线控制器和微程序控制器
  • STM32之火焰传感器模块(四针)
  • 11、类加载器
  • 项目:数据库应用系统开发:智能电商管理系统
  • 【Springai】项目实战进度和规划
  • 【FR801xH】富芮坤FR801xH之PMU GPIO
  • OpenCV CUDA模块设备层----- 正切(tangent)运算函数tan()
  • Python 数据分析与机器学习入门 (五):Matplotlib 数据可视化基础
  • R1-Searcher使用强化学习增强语言模型解决问题的搜索能力
  • WebSocket 的核心原理和工作流程
  • 前端Vue面试八股常考题(一)
  • 企业流程知识:《超越再造:以流程为中心的组织如何改变我们的工作和生活》读书笔记
  • 力扣面试150(7/150)
  • 【c/c++2】多线程,动静态库,信号,socket
  • 如何让宿主机完全看不到Wi-Fi?虚拟机独立联网隐匿上网实战!
  • 【知识图谱构建系列7】:结果评价(1)
  • 可编辑39页PPT | 数字化工厂蓝图整体框架建设举措建设路径实施路线规划建设方案
  • 从入门到精通:npm、npx、nvm 包管理工具详解及常用命令
  • Microsoft Edge 打开无反应、打开后显示兼容性问题、卸载重装 解决方案。一键卸载Microsoft Edge 。
  • 卫朋:华为流程体系拆解系列——IPD流程L1-L6分级导入实战演练
  • android BottomSheet及AlertDialog的几种material3 常见ui的用法
  • vue上传各种文件,并预览组件,(预览,下载),下载resources目录下文件