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

时间:2018-10-15 23:28:51

标签: ios iframe webkit focus mobile-safari

我已经在StackOverflow和各种Apple / WebKit错误报告系统上搜索了此特定问题,但是还没有找到专门引用的内容(似乎不太可能)。

问题: 在我们的付款页面上,我们有各种表单字段(输入和选择)。出于PCI /安全性的目的,我们有一个iframe服务于信用卡号字段(iframe仅 具有该字段-别无其他)。

问题是,对于 just 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个独立的bug。第一个主要是如上所述,但似乎更多是一个渲染问题,iOS看起来并没有像将焦点放在某个字段上那样。但是,如果您转到 codepen示例 new example,则我将按照以下步骤进行设置,即使看起来好像不是该字段具有焦点,但如果键入,文本将正确显示

第二个问题不太可能发生,但更有害。跳闸需要3个条件:

  1. iframe的来源必须是跨源的
  2. 父页面正在将事件侦听器附加到touchstart,touchmove或touchend(甚至像一个空函数调用一样简单)
  3. 当另一个字段具有焦点并且存在键盘时,iframe的字段将不在屏幕上。

这三件事的结果是用户根本无法将焦点放在iframe字段上(尽管document.activeElement显示了最后一个具有焦点的父页面输入),键入没有任何作用。重新建立在iframe中获得焦点的能力可能很困难,通常需要在iframe字段可见时具有可聚焦的父页面输入,然后用户才能将焦点移至iframe字段从那里。

如果更改了3个条件中的任何一个(不是跨域的,则在这3个触摸事件或iframe上都没有事件侦听器可见),那么仅会出现第一个(抑制程度较小)错误。

我还将通过这种认识来更新下面的“答案”。

更新2:实际的new example I put up shows both bugs;第一页是Bug#1,其中包含指向跨域Bug#2示例的链接。

4 个答案:

答案 0 :(得分:3)

我相信我已经找到了解决此令人沮丧的小错误的修补程序,并且像大多数错误一样,它是一个非常简单的修补程序。

所有要做的就是将以下CSS应用于iframe中的输入。

    input:hover {
        cursor: text
    }

这是一个更新的示例:https://codepen.io/ryanoutloud/project/full/AEKGjj

现在,关于错误本身,焦点实际上在预期的字段上,并且键盘上的任何输入都将正确注册。键入开始后,插入符号会跳到正确的位置。
我在ontouchstart=""解决方案中发现的问题是,一旦将焦点放在某个字段上,它便完全将插入符号从视图中移出了。

答案 1 :(得分:2)

在我的环境中,通过在IFrame中添加@Ryan L的建议document.addEventListener('touchstart', {});解决了问题。

这很好,因为添加起来非常简单并且特定于IFrame,不会影响容器页面。

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

答案 2 :(得分:0)

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

这来自this WebKit bug上提供的一种变通方法,该变通方法与外部页面点击事件未正确分配到iframe(在缩放的情况下)相关。

我尚未将其推向生产阶段,但初步测试似乎表明该方法可行。我确实必须将其放在父级和iframe表单元素上才能完全解决此问题。我可能会利用JavaScript将其附加到表单字段,而无需将属性添加到每个表单元素。

对此方法还有其他建议或疑虑。

答案 3 :(得分:0)

这对我有用

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