iOS 7 Safari:单击/聚焦HTML输入时,操作系统会锁定4秒钟

tra*_*roy 38 iphone safari input ipad ios7

更新:问题似乎源于页面上有许多选择元素.这有多随机?

所以这就是问题所在.在iOS 7 Safari上,当点击我网站上的文本输入时,键盘会打开,然后将操作系统冻结约2-5秒,最后滚动到输入.发生这种情况后,在刷新页面之前,它永远不会再发生.我到处都看了,是的,iOS 7 Safari是超级越野车,但我们试着看看我们是否可以解决这个问题.

注意:这不会发生在任何其他移动浏览器或任何以前的iOS Safari中.它发生在ios 7 iphone和ios 7 ipad上.

我会列出我和朋友到目前为止所做的一切:

  • 删除了在jQuery中添加事件处理程序的功能.(注意:除了unload和onpageshow之外,我们所有的事件处理程序都是通过jQuery分配的).
  • 从输入中删除了jQuery自动完成脚本.
  • 从输入中删除了所有JavaScript.
  • 通过拒绝Mac上的域删除了页面上添加的所有第三方库.
  • 切换回以前的jQuery版本.在没有任何效果之前我们实际可以使用的最后一个是1.7.0.
  • 切换回以前的jQuery UI版本.
  • 将输入事件处理更改为委派和生效,而不是('click')
  • 删除了所有CSS类.
  • 从页面中删除了所有CSS.注意:操作系统的响应时间减少到1-2秒但仍然发生.

有没有人有任何想法?

谢谢你!

Jas*_*man 13

(有一些有效的解决方案,请参阅列表末尾附近)

在我的公司,我们也受此影响.我们向Apple提出了一个问题,但听说过妈妈.

这里有一些有趣的jsfiddles来帮助说明一些问题,它肯定似乎围绕着隐藏字段的数量,而textareas似乎并没有受到影响.

从调试工作来看,我的猜测是有一些功能试图检测输入是信用卡还是电话号码或某种特殊类型,这似乎会导致锁定行为.这只是一个假设..

摘要:

在包含名为"display:none"的容器内的命名输入元素的表单的页面上,第一次按下该表单的输入在键盘出现和输入聚焦之间有一个非常明显的延迟(20秒-2分钟) .这可以防止用户使用我们的网络应用程序,因为ui冻结等待键盘响应的时间很长.我们已经在各种场景中对其进行了调试,以尝试识别正在发生的事情,这似乎是因为iOS7解析DOM的方式与iOS6上的方式有所不同,而iOS6没有这些问题.

通过连接iPad的Safari的Inspector中的调试,我们发现iOS7提供了有关(程序)活动的更多信息,我们发现_CollectFormMetaData是问题的父级.搜索元数据会导致大量的流失,并且随着包含输入的隐藏容器的数量而增加.我们发现_isVisible和_isRenderedFormElement的调用远远超过他们合理应该的范围.此外,如果它有帮助,我们发现一些与信用卡和地址簿相关的检测功能是大量的时间消费者.

这里有一些jsFiddles用于说明.请在运行iOS6的iPad上以及运行iOS7的iPad上的Safari中查看它们:

http://jsfiddle.net/gUDvL/20/ - 两者都运行良好

http://jsfiddle.net/gUDvL/21/ - iOS 7上的延迟很明显

http://jsfiddle.net/gUDvL/22/ - iOS 7更加明显的延迟

http://jsfiddle.net/gUDvL/29/ - iOS 7上非常明显的延迟

http://jsfiddle.net/gUDvL/30/ - 与29相同但没有隐藏 - 在iOS 7上没有延迟

http://jsfiddle.net/gUDvL/38/ - 与29相同,但进一步恶化

http://jsfiddle.net/gUDvL/39/ - 99个隐藏的输入,一个可见,一个可见

http://jsfiddle.net/gUDvL/40/ - 99个隐藏的textareas,一个可见,一个可见

http://jsfiddle.net/gUDvL/41/ - 99个隐藏的输入,一个可见,一个单独可见,都具有autocomplete ="off"属性

http://jsfiddle.net/gUDvL/42/ - 99个隐藏的输入,一个可见,一个可见.绝对位置隐藏而左侧而不是显示.

http://jsfiddle.net/gUDvL/63/ - 与gUDvL/43 /相同,但具有自动完成功能,自动更正功能,自动注册功能和拼写检查功能

http://jsfiddle.net/gUDvL/65/ - 与gUDvL/63 /相同,但清理后的缩进(在iPad上显得比较慢)

http://jsfiddle.net/gUDvL/66/ - 与gUDvL/65 /相同,但是再次显示none css而不是DOMReady jQuery

http://jsfiddle.net/gUDvL/67/ - 与gUDvL/66相同,但与TedGrav的焦点/模糊技术相同

http://jsfiddle.net/gUDvL/68/ - 与gUDvL/66 /相同,但使用css驱动的text-indent而不是display:block (显着改进 - 初始焦点减少到2-3秒)

http://jsfiddle.net/gUDvL/69/ - 与gUDvL/68 /相同,但重新添加了TedGrav的焦点/模糊

http://jsfiddle.net/gUDvL/71/ - 与gUDvL/66 /相同,但js在每次输入之前添加了一个图例标记.(明显改善 - 初始焦点减少到2-3秒)

<input type="text" autocomplete="off" /> (links to jsfiddle.net must be accompanied by code..)
Run Code Online (Sandbox Code Playgroud)

(我们应该注意到,将iPad连接到带有Safari调试器的Mac上可以大大强调延迟.)

重现步骤:

  1. 在iPad上加载任何上述jsfiddles
  2. 按输入可获得焦点
  3. 观看屏幕,直到您可以输入

预期成绩:

键盘弹出后,可以立即输入

实际结果:

观看键盘弹出和屏幕冻结,无法滚动或与Safari交互一段时间.在持续时间之后,焦点按预期给出.从那时起,在关注输入时不会发生进一步的冻结.

tl; dr技术摘要

总的来说,从各种答案中提出了几个建议的修复:

  • 不要使用display:none隐藏div - 使用text-indent之类的东西
  • 短路Apple的元数据扫描逻辑 - 许多表单标签或图例标签似乎都可以解决问题
  • 自动对焦/模糊 - 对我来说没有用,但有两个人报告了它

Apple的相关主题:

https://discussions.apple.com/thread/5468360


Bin*_*nke 7

IOS如何处理输入和textareas 的触摸事件似乎存在问题.当DOM变大时,延迟变大.然而焦点事件没有问题!

若要解决此问题,您可以覆盖touchend事件并将焦点设置为输入/ textarea.

document.addEventListener("touchend", function (e) {  
     if (e.target.nodeName.toString().toUpperCase() == 'INPUT' || e.target.nodeName.toString().toUpperCase() == 'TEXTAREA') {  
         e.preventDefault(); 
         e.target.focus(); 
     } 
});
Run Code Online (Sandbox Code Playgroud)

然而,这将产生新问题.它会让您在触摸输入/文本区域时滚动页面,但是当您松开时,该站点将滚动回原始位置.

要解决此问题,您只需检查是否发生了任何滚动,并使用if语句包围preventDefaulttarget.focus.

要设置原始位置,可以使用touchstart事件.

document.addEventListener("touchstart", function (e) {
    ... //store the scrollTop or offsetHeight position and compare it in touchend event.
}
Run Code Online (Sandbox Code Playgroud)

编辑我和一位同事已经改进了一点,它就像一个魅力.

var scroll = 0; 
document.addEventListener("touchstart", function (e) { 
    scroll = document.body.scrollTop; 
 });   

document.addEventListener("touchend", function (e) { 
    if (scroll == document.body.scrollTop) { 
        var node = e.target.nodeName.toString().toUpperCase(); 
        if (node == 'INPUT' || node == 'TEXTAREA' || node == 'SELECT') { 
            e.preventDefault(); 
            e.target.focus(); 
            if(node != 'SELECT') {
                var textLength = e.target.value.length; 
                e.target.setSelectionRange(textLength, textLength);
            }
        } 
    } 
}); 
Run Code Online (Sandbox Code Playgroud)