iOS 10-12 WebKit (Safari/Chrome) iframe 焦点错误的解决方法
Workaround for iOS 10-12 WebKit (Safari/Chrome) iframe focus bug
我已经在 Whosebug 和各种 Apple/WebKit 错误报告系统上搜索了这个特定问题,但尚未找到具体引用的问题(这似乎不可能)。
问题:
在我们的支付页面上,我们有各种表单字段(输入和选择)。出于 PCI/security 目的,我们有一个 iframe 服务于信用卡号字段(iframe 只有 有那个字段 - 没有别的)。
问题是 只是 iOS 用户,他们有时无法将焦点放在信用卡号字段上. 似乎有 2 个不同但相关的 iOS webkit 错误。请参阅下面的更新。
如果他们只是从一个字段向下导航到另一个字段,通常会奏效。但是,如果他们在字段中跳来跳去,他们可能会遇到这样的情况:他们可能会尝试 他们无法将焦点放在信用卡号码字段中 它看起来不像信用卡片字段获得焦点(似乎是渲染问题)。
最初我们认为可能有 JS 或一些不可见的 DIV 妨碍了我们,但我最终能够创建一个 HTML-only example to recreate the problem。 (关于如何重新创建问题的说明在示例页面上。)链接到 codepen 需要我包含一些代码:
<iframe src="iframe.html"></iframe>
我一直能够在 iOS 10-12 台设备上重现此问题(iOS 9 台设备似乎没有问题)。
为了后代,我将提供我在一个单独但半相关的 WebKit 错误中遇到的解决方法。但是,我想知道其他人是否偶然发现了这个问题并发现了其他解决方法。
更新:
深入研究后,我发现我们遇到了 2 个不同的错误。第一个主要是我上面描述的,但似乎更像是一个渲染问题,其中 iOS 并不 看起来 就像它把焦点放在一个字段上。但是,如果您转到 codepen 示例 new example 我设置并按照步骤操作,即使它看起来不像该字段具有焦点,如果您键入文本将正确呈现。
第二个问题发生的可能性较小,但危害更大。它需要 3 个条件才能跳闸:
- iframe 的来源必须是跨源的
- 父页面正在将事件侦听器附加到 touchstart、touchmove 或 touchend(甚至像空函数调用一样简单)
- 当另一个字段具有焦点并且存在键盘时,iframe 的字段在屏幕外。
这 3 件事的结果是用户根本无法将焦点放在 iframe 字段上(尽管 document.activeElement 显示最后一个具有焦点的父页面输入,但打字无处可去)。重新建立在 iframe 中获得焦点的能力可能很困难,通常需要有一个可以在 iframe 字段 visible 时聚焦的父页面输入,然后用户可以将焦点移动到那里的 iframe 字段。
如果更改了 3 个标准中的任何一个(不是跨域,这 3 个触摸事件上没有事件侦听器或 iframe 可见),那么只有第一个 - 不太禁止 - 存在错误。
我也会根据这一认识更新下面的“答案”。
更新 2: new example I put up shows both bugs 在行动;第一页是 Bug #1,带有 link 到跨源 Bug #2 示例。
这是我偶然发现的解决方法:向每个表单输入元素添加 ontouchstart=""
(也可能选择)。
这来自 this WebKit bug 上提供的解决方法之一,与外部页面点击事件没有正确分派到 iframe(在缩放上下文中)有关。
我还没有将其投入生产,但初步测试似乎表明它有效。我确实必须将它放在父表单元素和 iframe 表单元素上才能完全解决问题。我可能会利用 JavaScript 将其附加到表单字段,而无需将 属性 添加到每个表单元素。
接受任何其他关于此方法的建议或疑虑。
我相信我已经找到了解决这个令人沮丧的小错误的方法,并且与大多数错误一样,这是一个非常简单的修复方法。
所有需要做的就是将以下 css 应用于 iframe 中的输入。
input:hover {
cursor: text
}
这是一个更新的例子:https://codepen.io/ryanoutloud/project/full/AEKGjj
现在关于错误本身,焦点实际上在预期的字段上,键盘上的任何输入都将被正确注册。一旦开始打字,插入符号就会跳到正确的位置。
我在 ontouchstart=""
解决方案中发现的问题是,一旦焦点放在某个字段上,它就会完全从视图中删除插入符号。
通过在 IFrame 中添加@Ryan L 的建议 document.addEventListener('touchstart', {});
,问题在我的环境中得到解决。
这很好,因为它添加起来非常简单,并且特定于 IFrame,不会影响容器页面。
问题描述:无法在 iDevices(phone 和 pad)上 'touch'(select,编辑)Safari 运行 上的另一个表单域 运行 iOS 12. 这只会发生在容器页面添加了一些触摸事件的 IFrame 中的页面上。非常模糊的一组条件,难以调试。
这对我有用
document.addEventListener('keydown', function(e) {
window.focus()
$(':focus').focus()
});
我已经在 Whosebug 和各种 Apple/WebKit 错误报告系统上搜索了这个特定问题,但尚未找到具体引用的问题(这似乎不可能)。
问题: 在我们的支付页面上,我们有各种表单字段(输入和选择)。出于 PCI/security 目的,我们有一个 iframe 服务于信用卡号字段(iframe 只有 有那个字段 - 没有别的)。
问题是 只是 iOS 用户,他们有时无法将焦点放在信用卡号字段上. 似乎有 2 个不同但相关的 iOS webkit 错误。请参阅下面的更新。
如果他们只是从一个字段向下导航到另一个字段,通常会奏效。但是,如果他们在字段中跳来跳去,他们可能会遇到这样的情况:他们可能会尝试 他们无法将焦点放在信用卡号码字段中 它看起来不像信用卡片字段获得焦点(似乎是渲染问题)。
最初我们认为可能有 JS 或一些不可见的 DIV 妨碍了我们,但我最终能够创建一个 HTML-only example to recreate the problem。 (关于如何重新创建问题的说明在示例页面上。)链接到 codepen 需要我包含一些代码:
<iframe src="iframe.html"></iframe>
我一直能够在 iOS 10-12 台设备上重现此问题(iOS 9 台设备似乎没有问题)。
为了后代,我将提供我在一个单独但半相关的 WebKit 错误中遇到的解决方法。但是,我想知道其他人是否偶然发现了这个问题并发现了其他解决方法。
更新:
深入研究后,我发现我们遇到了 2 个不同的错误。第一个主要是我上面描述的,但似乎更像是一个渲染问题,其中 iOS 并不 看起来 就像它把焦点放在一个字段上。但是,如果您转到 codepen 示例 new example 我设置并按照步骤操作,即使它看起来不像该字段具有焦点,如果您键入文本将正确呈现。
第二个问题发生的可能性较小,但危害更大。它需要 3 个条件才能跳闸:
- iframe 的来源必须是跨源的
- 父页面正在将事件侦听器附加到 touchstart、touchmove 或 touchend(甚至像空函数调用一样简单)
- 当另一个字段具有焦点并且存在键盘时,iframe 的字段在屏幕外。
这 3 件事的结果是用户根本无法将焦点放在 iframe 字段上(尽管 document.activeElement 显示最后一个具有焦点的父页面输入,但打字无处可去)。重新建立在 iframe 中获得焦点的能力可能很困难,通常需要有一个可以在 iframe 字段 visible 时聚焦的父页面输入,然后用户可以将焦点移动到那里的 iframe 字段。
如果更改了 3 个标准中的任何一个(不是跨域,这 3 个触摸事件上没有事件侦听器或 iframe 可见),那么只有第一个 - 不太禁止 - 存在错误。
我也会根据这一认识更新下面的“答案”。
更新 2: new example I put up shows both bugs 在行动;第一页是 Bug #1,带有 link 到跨源 Bug #2 示例。
这是我偶然发现的解决方法:向每个表单输入元素添加 ontouchstart=""
(也可能选择)。
这来自 this WebKit bug 上提供的解决方法之一,与外部页面点击事件没有正确分派到 iframe(在缩放上下文中)有关。
我还没有将其投入生产,但初步测试似乎表明它有效。我确实必须将它放在父表单元素和 iframe 表单元素上才能完全解决问题。我可能会利用 JavaScript 将其附加到表单字段,而无需将 属性 添加到每个表单元素。
接受任何其他关于此方法的建议或疑虑。
我相信我已经找到了解决这个令人沮丧的小错误的方法,并且与大多数错误一样,这是一个非常简单的修复方法。
所有需要做的就是将以下 css 应用于 iframe 中的输入。
input:hover {
cursor: text
}
这是一个更新的例子:https://codepen.io/ryanoutloud/project/full/AEKGjj
现在关于错误本身,焦点实际上在预期的字段上,键盘上的任何输入都将被正确注册。一旦开始打字,插入符号就会跳到正确的位置。
我在 ontouchstart=""
解决方案中发现的问题是,一旦焦点放在某个字段上,它就会完全从视图中删除插入符号。
通过在 IFrame 中添加@Ryan L 的建议 document.addEventListener('touchstart', {});
,问题在我的环境中得到解决。
这很好,因为它添加起来非常简单,并且特定于 IFrame,不会影响容器页面。
问题描述:无法在 iDevices(phone 和 pad)上 'touch'(select,编辑)Safari 运行 上的另一个表单域 运行 iOS 12. 这只会发生在容器页面添加了一些触摸事件的 IFrame 中的页面上。非常模糊的一组条件,难以调试。
这对我有用
document.addEventListener('keydown', function(e) {
window.focus()
$(':focus').focus()
});