iOS 10-12 WebKit(Safari / Chrome)iframe焦点错误的解决方法

19
我在StackOverflow和各种Apple/WebKit错误报告系统中搜索了这个特定问题,但还没有找到具体引用它的内容(这似乎不可能)。
问题是:在我们的付款页面上,我们有各种表单字段(输入和选择)。出于PCI/安全目的,我们有一个iframe来提供信用卡号字段(该iframe仅有该字段-没有其他内容)。
对于仅iOS用户,问题在于他们有时无法将焦点放在信用卡号字段上。看起来有两个不同但相关的iOS WebKit错误。如果他们只是从一个字段导航到另一个字段,通常可以解决问题。但是如果他们在字段之间反弹,他们会陷入一种情况,尽管他们会尝试,但似乎无法将焦点放在信用卡号字段上(似乎是呈现问题)。
最初,我们认为可能是JS或某些不可见DIV挡住了路,但我最终能够创建一个仅HTML示例以重现问题。(如何重现该问题的说明在示例页面上。)链接到codepen需要我包含一些代码:
<iframe src="iframe.html"></iframe>

我一直能够在iOS 10-12设备上重现此问题(iOS 9设备似乎没有这个问题)。

为了记录,我将提供一个与WebKit bug有关但是半相关的解决方法。然而,我想知道是否有其他人遇到过这个问题并发现了其他解决方法。

更新:

经过进一步的挖掘,我发现我们遭受了两个不同的错误。第一个错误大多如我上面所描述的,但似乎更像是iOS没有将焦点放在字段上的呈现问题。然而,如果您转到新示例我设置的地方并按照步骤操作,即使看起来该字段没有焦点,如果您键入文本,它也会正确呈现。

第二个问题不太可能发生,但更为严重。它需要满足三个条件:

  1. iframe的源必须是跨域的
  2. 父页面正在附加一个事件侦听器以touchstart、touchmove或touchend(甚至只是一个空函数调用)
  3. 当不同的字段具有焦点并且键盘存在时,iframe的字段不在屏幕上。
这三个条件的结果是用户无法在iframe字段上放置焦点(尽管document.activeElement显示最后一个父页面输入具有焦点,但打字不起作用)。重新建立对iframe中焦点的获取能力可能很困难,通常需要一个可以在iframe字段可见时聚焦的父页面输入,然后用户可以从那里将焦点移动到iframe字段。
如果更改了这三个条件中的任何一个(非跨域,这三个触摸事件上没有事件侦听器或者iframe可见),则只存在第一个-限制较少的-错误。
我也会根据这个认识更新下面的“答案”。
更新2:我提供的新示例展示了这两个错误;第一个页面是Bug#1,链接到跨源Bug#2示例。

2
通过在IFrame中添加@Ryan L的建议document.addEventListener('touchstart', {});,我的环境中的问题已经解决。 - GlennG
4个回答

13

在我的环境中,通过添加@Ryan L的建议document.addEventListener('touchstart', {});来解决问题。这很好,因为它非常简单且特定于IFrame,不会影响容器页面。

问题描述:在运行iOS 12的iDevices(手机和平板电脑)上的Safari上,无法“触摸”(选择、编辑)另一个表单字段。这仅发生在容器页面添加了一些触摸事件的IFrame页面上。非常模糊的条件很难调试。


5

我相信我已经找到了解决这个令人沮丧的小错误的方法,就像大多数错误一样,这是一个超级简单的修复方法。

需要做的就是将以下css应用于iframe内的输入框。

    input:hover {
        cursor: text
    }

这是一个更新的示例:https://codepen.io/ryanoutloud/project/full/AEKGjj 现在关于错误本身,重点实际上在于所预期的字段,键盘输入的任何内容将被正确地注册。一旦开始输入,插入符号跳到正确的位置。我发现使用ontouchstart=""方法解决问题的问题在于,一旦聚焦在一个字段上,它会完全将插入符号从视野中删除。

嗨,Ryan,感谢你进一步深入研究这个问题。看起来你的解决方法比“ontouchstart”更好。然而,这个修复只似乎缓解了我在帖子中更新的两个错误中的第一个(渲染问题)。对于第二个(更有影响力但也不太典型的)错误,你有什么想法吗?我无法使用codepen创建跨源iframe测试,所以我在Azure上建立了一个简单的示例。登陆页面显示Bug#1(带有切换CSS修复的按钮),顶部有一个链接到Bug#2。已更新原始帖子并附上链接。 - J Stuart
FYI,我们正在测试的有关漏洞#1的解决方法更加专注(为了排除单选框和复选框获取文本光标):input[type=text]:hover, input[type=number]:hover, input[type=email]:hover, input[type=tel]:hover, input[type=password]:hover, textarea:hover {cursor: text} - J Stuart
3
J,请确保问题#1的解决方法仅适用于iframe,而不是父级页面。另外,请尝试在iframe内添加以下内容。这个组合似乎可以从我的角度修复问题1和2。document.addEventListener('touchstart', {}); - Ryan L.
1
@Ryan,我终于有机会将你建议的iframe修复程序添加到一个新的示例页面中。似乎在_iframe_源代码中添加的document.addEventListener可以解决Bug #1和#2 - 至少在iframe内部是这样的。当从父页面的输入框中退出iframe时,Bug #1仍然存在问题(请参见示例),但与原始的两个错误相比,这个问题相对较小。谢谢! - J Stuart
1
@Ryan:请更新这个答案,加上 document.addEventListener('touchstart', {}); 这段代码;它解决了我在 IFrame 中遇到的极其恼人的问题。 - GlennG

0

这是我偶然发现的解决方法:在每个表单输入元素中添加ontouchstart = ""(可能也包括选择器)。

这来自于这个WebKit bug提供的其中一个解决方法,该问题与外部页面点击事件无法正确分派到iframe有关(在缩放的情况下)。

我还没有将其推向生产环境,但最初的测试似乎表明这有效。我确实不得不将其放在父级和iframe表单元素上才能完全解决问题。我可能会利用JavaScript将其附加到表单字段,而无需将属性添加到每个表单元素。

欢迎任何其他建议或对此方法的关注。


0

这对我有用

document.addEventListener('keydown', function(e) {
  window.focus()
  $(':focus').focus()
});

2
提供的答案因为质量较低而被标记为待审核。以下是一些关于如何撰写好的回答的指南:How do I write a good answer?。这个提供的答案可能是正确的,但它可以从解释中受益。仅有代码的答案不被认为是“好”的答案。来自review - MyNameIsCaleb
一个仅包含代码的答案是低质量答案。请加入一些解释来说明这段代码片段是如何工作的。 - Taslim Oseni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接