web-dev-qa-db-ja.com

iOS 10-12 WebKit(Safari / Chrome)iframeフォーカスバグの回避策

この特定の問題をStackOverflowとさまざまなApple/WebKitバグレポートシステムでここで検索しましたが、具体的に引用されたものはまだ見つかりません(これは不可能だと思われます)。

問題:支払いページには、さまざまなフォームフィールド(入力と選択)があります。 PCI /セキュリティの目的で、クレジットカード番号フィールドを提供するiframeがあります(iframeonlyにはその1つのフィールドがあり、他には何もありません)。

問題は、justiOSユーザーの場合、クレジットカード番号フィールドに焦点を当てることができない場合があることです。 2つの異なるが、関連するiOS Webkitのバグがあるようです。以下の更新を参照してください。

あるフィールドから別のフィールドに移動するだけであれば、通常は機能します。しかし、彼らがフィールドを跳ね回る場合、彼らは試してみるというシナリオに入ることができます 彼らはクレジットカード番号フィールドに焦点を合わせることができません クレジットカードフィールドがフォーカスを取得しているようには見えません(レンダリングの問題のようです)。

最初は、JSや目に見えないDIVが邪魔をするかもしれないと思っていましたが、最終的に 問題を再現するためのHTMLのみの例 を作成することができました。 (問題の再現方法の説明はサンプルページにあります。)codepenにリンクするには、いくつかのコードを含める必要があります。

<iframe src="iframe.html"></iframe>

私は一貫して、iOS 10-12デバイスでこの問題を再現することができました(iOS 9デバイスには問題がないようです)。

後世のために、別の、しかし半関連のWebKitバグで遭遇した回避策を提供します。しかし、他の人がこの問題に出くわし、他の回避策を発見したのではないかと思っていました。

更新:

さらに掘り下げた後、2つの別々のバグに苦しんでいることがわかりました。 1つ目は主に上記で説明したとおりですが、iOSがフィールドに焦点を当てているようにlookしていないレンダリングの問題のようです。ただし、に行く場合 コードペンの例 新しい例 フィールドにフォーカスがあるように見えない場合でも、テキストを入力すると正しくレンダリングされます。

2番目の問題は発生する可能性は低くなりますが、より有害です。トリップには3つの基準が必要です。

  1. Iframeのソースはクロスオリジンでなければなりません
  2. 親ページは、touchstart、touchmove、touchendのいずれかにイベントリスナーをアタッチしています(空の関数呼び出しのように単純な場合でも)
  3. 別のフィールドにフォーカスがあり、キーボードが存在する場合、iframeのフィールドはオフスクリーンです。

これら3つのことの結果、ユーザーはiframeフィールドにフォーカスをまったく置くことができません(document.activeElementはフォーカスを持つ最後の親ページ入力を示しますが、入力はどこにも行きません)。 iframeでフォーカスを取得する機能を再確立するのは困難な場合があります。通常、iframeフィールドが表示されている間にフォーカスできる親ページ入力が必要です。そこからiframeフィールドにフォーカスします。

3つの基準のいずれかが変更された場合(クロスドメインではなく、これらの3つのタッチイベントのイベントリスナーが表示されないか、iframeが表示されない場合)、最初の-禁止の少ないバグのみが存在します。

この実現についても、以下の「回答」を更新します。

更新2:私が立てた新しい例は両方のバグを示しています アクション;最初のページはバグ#1で、クロスオリジンバグ#2の例へのリンクがあります。

15
J Stuart

私の環境では、IFrameに@Ryan Lの提案document.addEventListener('touchstart', {});を追加することで問題が解決します。

追加するのは非常に簡単で、IFrameに固有であり、コンテナページには影響しないため、これは良いことです。

問題の説明:iOS 12を実行するiDevice(電話とパッド)で実行されるSafariの別のフォームフィールドを「タッチ」(選択、編集)できません。これは、コンテナページにタッチイベントが追加されたIFrameのページでのみ発生します。デバッグが難しい非常に不明瞭な条件のセット。

11
GlennG

私はこのイライラする小さなバグの修正を見つけたと信じており、ほとんどのバグのようにそれは非常に簡単な修正です。

行う必要があるのは、iframe内の入力に次のCSSを適用することだけです。

    input:hover {
        cursor: text
    }

更新された例を次に示します。 https://codepen.io/ryanoutloud/project/full/AEKGjj

バグ自体については、実際には目的のフィールドに焦点が当てられており、キーボードからの入力はすべて正しく登録されます。入力が始まると、キャレットが適切な位置にジャンプします。の
ontouchstart=""解決策は、フィールドにフォーカスが置かれると、ビューからキャレットを完全に削除するだけです。

4
Ryan L.

ここに私がつまずいた回避策があります:add ontouchstart=""を各フォーム入力要素に(おそらく選択します)。

これは このWebKitのバグ で提供されている回避策の1つに由来します(=ズームのコンテキストで)iframeに適切にディスパッチされない外部ページクリックイベントに関連します。

私はまだこれを本番環境にプッシュしていませんが、最初のテストではこの動作を示しているようです。問題を完全に修正するには、親フォーム要素とiframeフォーム要素の両方にこれを配置する必要がありました。おそらくJavaScriptを使用して、各フォーム要素にプロパティを追加することなく、これをフォームフィールドに添付します。

このアプローチに関する他の提案や懸念を受け入れます。

0
J Stuart

私のためのこの仕事

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