问题描述

ios 11.3以上,input输入框点击多次才能获取输入框焦点,弹出输入键盘

daily环境事例

问题定位

1.怀疑是输入框设置padding,导致input的高度很小,可点击范围很小。

改动后,去掉padding,设置height和line-height, 点击范围扩大。
解决了点击范围的问题,但是仍然无法focus弹起键盘

2.搜索baidu

第一个相似答案:

  1. Android : input框有内容搜索跳转后,按返回键,input不能聚焦,键盘不弹出
  2. IOS : 正常进入页面input框不能聚焦,键盘不弹出,多次点击可能会聚焦
  3. user-select
  4. 语法:
  5. user-selectnone |text| all | element
  6. 默认值:text
  7. 适用于:除替换元素外的所有元素
  8. 继承性:无
  9. 动画性:否
  10. 计算值:指定值
  11. 取值:
  12. none
  13. 文本不能被选择
  14. text
  15. 可以选择文本
  16. all
  17. 当所有内容作为一个整体时可以被选择。如果双击或者在上下文上点击子元素,那么被选择的部分将是以该子元素向上回溯的最高祖先元素。
  18. element
  19. 可以选择文本,但选择范围受元素边界的约束

这个是定义输入框是否可以被选择的,包括选择、全选等,
所以修改后问题依然存在。



第二个相似答案:

  1. FastClick.prototype.focus = function(targetElement) {
  2. var length
  3. // 组件建议通过setSelectionRange(selectionStart, selectionEnd)来设定光标范围(注意这样还没有聚焦
  4. // 要等到后面触发 sendClick 事件才会聚焦)
  5. // 另外 iOS7 下有些input元素(比如 date datetime month) 的 selectionStart 和 selectionEnd 特性是没有整型值的,
  6. // 导致会抛出一个关于 setSelectionRange 的模糊错误,它们需要改用 focus 事件触发
  7. var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !(navigator.userAgent.indexOf("Windows Phone") >= 0);
  8. if (
  9. deviceIsIOS &&
  10. targetElement.setSelectionRange &&
  11. targetElement.type.indexOf('date') !== 0 &&
  12. targetElement.type !== 'time' &&
  13. targetElement.type !== 'month'
  14. ) {
  15. length = targetElement.value.length
  16. targetElement.setSelectionRange(length, length)
  17. /* 修复bug ios 11.3以上不弹出键盘,这里加上聚焦代码,让其强制弹出键盘 */
  18. targetElement.focus()
  19. } else {
  20. //直接触发其focus事件
  21. targetElement.focus()
  22. }
  23. }

问题解决了。

fastClick 介绍

  1. 移动端浏览器在派发点击事件的时候,通常会出现300ms左右的延迟
  2. 原因: 移动端的双击会缩放导致click判断延迟

问题原因:

ios 11.3更新 Safari 11.1,支持新web API :允许对事件支持 {passive: false}被动模式,减少滚动屏幕的性能损耗和奔溃。

在ios更新日志了,写到了“Updated root document touch event listeners to use passive mode improving scrolling performance and reducing crashes.”

翻译过来就是:针对document的touch事件监听添加passive配置,即是:{passive: true},会永远不调用event.preventDefault(),以此来提高滚动性能。

  1. //示例代码
  2. target.addEventListener('touchstart', function(e){
  3. e.preventDefault() // 无效,报错
  4. }, {passive: true});

源头推测:

fastclick是采用拦截click和监听touch事件去实现的,里面包括对tagetElement的focus方法重写,因此在11.3之前可能event.preventDefault生效了,同时用setSelectionRange是可以聚焦input的。

  1. targetElement.setSelectionRange(length, length);”,目的是为了光标停留在输入内容的末尾,是引起输入框聚焦的原因,但仅仅执行这个函数还无法到达聚焦的效果



参考文献:
github issue
IOS11.3 fastclick.js相关bug
IOS11.3

深入浅出 React(三):理解 JSX 和组件
你真的了解FastClick吗

文档更新时间: 2019-06-28 12:47