38

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

所以这就是问题所在。在 iOS 7 Safari 上,当点击我网站上的文本输入时,键盘会打开,然后将操作系统冻结大约 2-5 秒,然后最终滚动到输入。在这种情况发生一次之后,它就不会再发生,直到您刷新页面。我到处查看,是的,iOS 7 Safari 是超级错误,但让我们试试看我们是否能解决这个问题。

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

我将列出我的朋友和我迄今为止尝试过的所有内容:

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

有没有人有任何想法?

非常感谢!

4

13 回答 13

13

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

在我的公司,我们也深受其害。我们向 Apple 提出了问题,但听到了妈妈的声音。

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

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

概括:

在具有包含标记为“显示:无”的容器内的命名输入元素的表单的页面上,第一次按下该表单中的输入在键盘出现和输入被聚焦之间有一个非常明显的延迟(20sec-2min) . 这会阻止用户使用我们的网络应用程序,因为用户界面冻结等待键盘响应所花费的大量时间。我们已经在各种场景中对其进行了调试,以尝试辨别发生了什么,这似乎是由于 iOS7 解析 DOM 的方式与 iOS6 上的方式发生了变化,而 iOS6 没有这些问题。

通过在连接 iPad 的情况下在 Safari 的 Inspector 中进行调试,我们发现 iOS7 提供了有关(程序)活动的更多信息,以至于我们发现 _CollectFormMetaData 是问题的根源。搜索元数据会导致大量流失,随着包含输入的隐藏容器数量的增加,流失率超过线性增长。我们发现 _isVisible 和 _isRenderedFormElement 的调用次数远远超过了它们合理的调用次数。此外,如果有帮助,我们发现一些与信用卡和地址簿相关的检测功能是大量消费者。

这里有一些用于说明的 jsFiddles。请在运行 iOS6 的 iPad 上的 Safari 中查看它们,然后在运行 iOS7 的 iPad 上查看它们:

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 个隐藏文本区域,一个可见,一个单独可见

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/ 相同,但再次通过 css 显示 none 而不是 DOMReady jQuery

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

http://jsfiddle.net/gUDvL/68/ - 与 gUDvL/66/ 相同,但使用 css 驱动的文本缩进而不是 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..)

(我们应该注意到,将 iPad 连接到带有 Safari 调试器的 Mac 会极大地强调延迟。)

重现步骤:

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

预期成绩:

期望能够在键盘弹出时立即输入

实际结果:

观看键盘弹出和屏幕冻结,在一段时间内无法滚动或与 Safari 交互。在持续时间之后,按预期给出焦点。从那时起,在专注于输入时不会再出现冻结。

tl;博士技术总结

因此,总的来说,有几个来自各种答案的建议修复:

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

Apple 的相关主题:

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

于 2014-01-30T00:12:13.523 回答
7

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

要解决此问题,您可以覆盖touchend事件并将焦点设置到输入/文本区域。

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

然而,这将产生一个新问题。它可以让您在触摸输入/文本区域时滚动页面,但是当您放手时,该站点将滚动回原始位置。

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

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

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

编辑我和一位同事对它进行了一些改进,它就像一个魅力。

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);
            }
        } 
    } 
}); 
于 2014-05-12T10:18:35.803 回答
4

在插入/删除包含单个输入元素的页面的 ios 全屏中也遇到了这个问题。页面上(以及整个 DOM 中)只有一个可见的文本输入元素时遇到了长达 30 秒的延迟。在同一 web 应用中具有单个或多个文本输入的其他动态插入页面没有遇到输入延迟。就像其他人提到的那样,在初始延迟之后,输入字段将在后续焦点事件上正常运行(即使包含输入元素的动态页面已从 DOM 中删除,然后动态地重新渲染/插入回 DOM)。

基于上述行为的预感,在页面加载时尝试了以下操作:

$("#problem-input").focus(); $("#problem-input").blur();

虽然上述内容立即执行,没有延迟,但最终结果是当输入通过用户交互获得焦点时没有后续延迟。无法解释此工作背后的原因,但它似乎对我的应用程序始终有效,而其他建议的修复程序都失败了。

于 2014-03-11T22:50:42.847 回答
3

我有同样的freezeing问题。

我不确定我们是否处于同样的情况。

这是我的演示:http ://tedzhou.github.io/demo/ios7sucks.html

在我的页面中,我使用<p>具有属性的元素onclick作为按钮。当用户单击按钮时,页面变为textarea. 然后单击它将冻结浏览器。

冻结所花费的时间与 dom 元素的数量有关。在我的页面中,有 10000 个元素,这使它冻结了 10 多秒。

我们可以通过将<p>元素切换为 real<button>或减少 dom 元素的数量来解决问题。

ps:对不起我的英语不好。哈哈

于 2013-10-15T12:10:04.570 回答
3

对我来说主要问题是隐藏字段。使表格挂起 10-15 秒。

我设法通过将隐藏的表单字段定位在屏幕之外来解决问题。


隐藏:

position: absolute;
left: -9999px;

显示:

position: relative;
left: 0;

于 2013-12-16T12:53:08.773 回答
1

在具有许多输入的相当复杂的应用程序中遇到了同样的问题。

通过 USB 将调试器附加到 Safari iOS7 并记录 UI 事件。当我单击 textarea(或任何输入)时,我会看到“touchend”事件发生,然后在 10-20 秒后,我看到“click”被分派。

显然这是 Safary 中的一个错误,因为在 Android 或 iOS6 等其他设备上,相同的应用程序没有问题。

于 2013-11-22T00:35:33.933 回答
1

它不仅发生在 iOS 中,而且在 MAC OS(Maverics)的 safari 7 中也发生,我发现当您使用大量 div 标签在表单中包含输入(或选择)时会发生问题:

<div> <select>...</select> </div>
<div> <select>...</select> </div>
...

我将选择的布局更改为使用 ul/li 和字段集而不是 div,并且冻结时间大大减少。

<ul>
   <li><select>...</select></div>
   <li><select>...</select></div>
</ul>

以下是 jsfiddle 中的两个示例:

冻结 5 秒

http://jsfiddle.net/k3j5v/5/

冻结 1 秒

http://jsfiddle.net/k3j5v/6/

我希望它可以帮助某人

于 2013-11-22T18:10:53.583 回答
1

对我来说,这个问题是由隐藏在页面上的用户输入引起的display:none

我使用的解决方法:我没有使用 隐藏输入display:none,而是在文档上使用 jQuery 的detach()方法准备“隐藏”所有未使用的用户输入。然后append()在需要时输入。

这样一来display:none,页面首次加载时就没有输入,因此初始用户交互不会出现延迟。

于 2014-07-15T11:19:08.117 回答
0

我们在我的公司遇到了相同或类似的问题。每当我们显示大量下拉列表,然后用户单击下拉列表时,IOS 7 就会将页面冻结一两分钟。在它解冻后,从那时起,一切都会正常工作。

这影响了所有输入类型。大量的下拉菜单实际上在第一次加载时就被隐藏了——用户会启动下拉菜单的显示。直到显示下拉菜单 - 一切都会正常工作。一旦它们显示出来,下一次输入点击,即使是一直正常工作的输入,现在都会导致浏览器冻结。

正如其他人所指出的,在用户第一次与输入交互之后,在解析 DOM 中的可见输入时,IOS 7 似乎存在问题。当元素/选项/DOM 的数量和/或复杂性更高时,冻结更加明显。

因为它总是在初始用户交互时冻结,所以我们决定在显示下拉列表后立即启动隐藏的用户操作。我们创建了一个透明按钮(它不能被隐藏——它必须被“显示”)并在用户打开下拉列表后立即点击它。我们原以为这样可以让 IOS 开始更快地解析 DOM,但发现它实际上完全解决了这个问题。

于 2014-02-04T20:17:20.460 回答
0

我也遇到了这个问题,因为我注意到很多人仍然有这个问题,我想我会提出我的解决方案。

基本上我的解决方案是服务器端隐藏元素。我的页面是 ASP.NET,所以我用 Panels 的输入包装了我的 div,并将这些面板设置为 Visible false。这样,如果我单击输入,Safari 将无法看到所有其他控件,因为它们是隐藏的服务器端。

当然,如果您想让这项工作有点像客户端 jquery,您将需要自动回发和某处的更新面板。此解决方案需要付出努力,但仍然比实际尝试修复 safari 错误要好。

希望这可以帮助。

于 2014-03-26T14:54:27.583 回答
0

我的回答可能稍微偏离了主题,但经过一番搜索后,我确实到达了这里,因为场景“感觉”很相似。

问题:

我的问题感觉像是 iOS 中的一个锁定,但不完全是,因为页面上的其他元素仍然是交互式的。我有一个<input type="search" />元素,当我单击该字段时不会聚焦。但它最终会在屏幕上点击 4-5 次后获得焦点。

附加信息:

我的项目是一个混合应用程序:iOS 应用程序内的 WebView。该网站是使用 Twitter Bootstrap 构建的。

解决方案:

我碰巧也在autofocus元素上设置了属性。我尝试删除它并且它起作用了......不再连续点击以使该领域聚焦。

于 2016-04-07T14:38:56.587 回答
0

iOS 12.1.1 - 2018 年 12 月

这是一个在我的案例中有效的简单修复:

window.scrollTo(0,0) // 附加到输入字段的“模糊”事件

虽然它在 UX 方面可能并不理想(尤其是如果您有一个包含许多字段的表单),但它绝对比 10 秒以上的冻结时间要好。

于 2018-12-15T15:00:04.687 回答
-2

您是否尝试在 Safari 设置中关闭“密码和自动填充”>“信用卡”?此操作后,它工作正常。这不是最终解决方案,但可能是 iOS 上问题的原因。

于 2014-04-14T15:01:58.423 回答