web-dev-qa-db-ja.com

iOS 7 Safari:HTML入力をクリック/フォーカスするとOSが4秒間ロックする

更新:この問題は、ページに多くの選択要素があることから生じているようです。これはどれくらいランダムですか?

ここに問題があります。 iOS 7 Safariでは、私のサイトでテキスト入力をタップすると、キーボードが開いてOSが約2〜5秒間フリーズし、最後に入力までスクロールします。これが一度発生すると、ページを更新するまで二度と発生しません。私はいたるところを調べましたが、そうです、iOS 7 Safariは非常にバグが多いですが、これを理解できるかどうか試してみましょう。

注:これは、他のモバイルブラウザーや以前のiOS Safariでは発生しません。 iOS 7 iPhoneとiOS 7 iPadの両方で発生します。

私は私の友人すべてをリストアップし、私がこれまでに試したことがあります:

  • JQueryにイベントハンドラーを追加する機能を削除しました。 (注:unloadとonpageshowを除いて、すべてのイベントハンドラーはjQueryを通じて割り当てられます)。
  • 入力からjQueryオートコンプリートスクリプトを削除しました。
  • 入力からすべてのJavaScriptを削除しました。
  • Macでドメインを拒否することにより、ページに追加されているすべてのサードパーティライブラリを削除しました。
  • 以前のjQueryバージョンに切り替えました。何も機能しないうちに実際に使用できる最後のバージョンは1.7.0でした。
  • 以前のjQuery UIバージョンに切り替えました。
  • 入力イベントの処理をon( 'click')ではなくデリゲートおよびライブに変更しました
  • すべてのCSSクラスを削除しました。
  • ページからすべてのCSSを削除しました。注:OSの応答時間は1〜2秒に短縮されましたが、それでも発生しました。

誰かアイデアはありますか?

本当にありがとう!

38
transformerTroy

(いくらか効果的なソリューションがあります。リストの最後近くを参照してください)

私の会社でもこれに苦しんでいます。 Apple=で問題を提出しましたが、お母さんの言うことを聞いたことがあります。

問題のいくつかを説明するのに役立つ興味深いjsfiddlesを以下に示します。これは、非表示フィールドの数を中心に展開しているようであり、textareasは影響を受けていないようです。

デバッグ作業から、入力がクレジットカードまたは電話番号であるか、ロック動作を引き起こすと思われる特別な種類であるかどうかを検出しようとする機能がいくつかあると私は推測しています。これは仮説の1つにすぎません。

概要:

「display:none」とマークされたコンテナー内の名前付き入力要素を含むフォームのあるページで、そのフォームの入力を最初に押すと、キーボードが表示されてから入力がフォーカスされるまでに非常に顕著な遅延(20秒-2分)があります。これにより、UIがフリーズしてキーボードが応答するのを待つのに膨大な時間が費やされるため、ユーザーがWebアプリを使用できなくなります。さまざまなシナリオでデバッグして何が起こっているのかを見極め、iOS7がDOMを解析する方法と、iOS6がDOMを解析する方法の変更によるものと思われますが、これらの問題はありません。

IPadが接続されたSafariのインスペクター内でのデバッグから、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の非表示の入力、1つは表示、もう1つは個別に表示

http://jsfiddle.net/gUDvL/40/ -99の非表示のテキスト領域、1つは表示、もう1つは個別に表示

http://jsfiddle.net/gUDvL/41/ -99個の非表示入力、1つは表示、1つは個別に表示、すべてautocomplete = "off"属性付き

http://jsfiddle.net/gUDvL/42/ -99の非表示入力、1つは表示、もう1つは個別に表示。絶対位置と表示ではなく左位置で非表示。

http://jsfiddle.net/gUDvL/63/ -gUDvL/43 /と同じですが、オートコンプリート、オートコレクト、オートキャピタライズ、スペルチェックがオフになります

http://jsfiddle.net/gUDvL/65/ -gUDvL/63 /と同じですが、インデントがクリーンアップされています(iPadでは遅いようです)

http://jsfiddle.net/gUDvL/66/ -gUDvL/65 /と同じですが、DOMReady jQueryの代わりにcssを介して何も表示しません。

http://jsfiddle.net/gUDvL/67/ -gUDvL/66 /と同じですが、TedGravのfocus/blurテクニックを使用します

http://jsfiddle.net/gUDvL/68/ -gUDvL/66 /と同じですが、display:blockの代わりにcss駆動のテキストインデントを使用します(noticeable改善-初期フォーカスで2〜3秒に短縮)

http://jsfiddle.net/gUDvL/69/ -gUDvL/68 /と同じですが、TedGravのfocus/blurが再度追加されています

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. 上記のjsfiddlesのいずれかをiPadにロードする
  2. 入力を押してフォーカスを取得します
  3. 入力できるまで画面を見る

予想される結果:

キーボードがポップアップしたらすぐにタイプできるようになると思います

実際の結果:

キーボードがポップアップして画面がフリーズし、スクロールしたりSafariをしばらく操作したりできないのを見てください。期間の後、フォーカスは期待どおりに与えられます。それ以降、入力に焦点を当てたときに、それ以上のフリーズは発生しません。

tl; drテクニックの要約

したがって、全体として、さまざまな回答から修正案がいくつか提案されています。

  • 表示でdivを非表示にしない:なし-テキストインデントのようなものを使用します
  • Appleのメタデータスキャンロジックの短絡-多くのフォームタグまたは凡例タグがうまく機能しているようです。
  • オートフォーカス/ぼかし-私にはうまくいきませんでしたが、2人の人がうまくいったと報告しました

Appleの関連スレッド:

https://discussions.Apple.com/thread/546836

13
Jasmine Hegman

IOSが入力とテキストエリアのtouch-eventを処理する方法に問題があるようです。遅延が大きくなりますDOMが大きくなったときですが、フォーカスイベントに問題はありません。

この問題を回避するには、touchendイベントをオーバーライドして、フォーカスをinput/textareaに設定します。

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

ただし、これにより新しい問題が発生します。入力/テキストエリアをタッチしながらページをスクロールできますが、離すとサイトは元の位置に戻ります。

これを修正するには、スクロールが発生したかどうかを確認し、preventDefaultおよびtarget.focusを囲むだけです。 ifステートメント。

元の位置を設定するには、touchstartイベントを使用できます。

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

[〜#〜] edit [〜#〜]私と同僚はそれを少し改善し、魅力のように動作しました。

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);
            }
        } 
    } 
}); 
7
Binke

この問題と、単一の入力要素を含むページを挿入/削除するiOSフルスクリーン内で苦労しました。ページ上(およびDOM全体)に表示されるテキスト入力要素が1つだけの場合、最大30秒の遅延が発生していました。同じwebappに単一または複数のテキスト入力がある他の動的に挿入されたページで、入力遅延が発生していませんでした。他の人が述べたように、初期遅延の後、入力フィールドは後続のフォーカスイベントで正常に動作します(入力要素を含む動的ページがDOMから削除され、動的に再レン​​ダリング/ DOMに挿入された場合でも)。

上記の動作に基づく直感で、ページの読み込み時に次のことを試しました。

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

上記は遅延なしですぐに実行されますが、最終的には、ユーザーの操作によって入力にフォーカスが移ったときに遅延が発生しません。この動作の背後にある理由を説明することはできませんが、他の提案された修正が失敗した間、それは私のアプリでは一貫して動作するようです。

3
TedGrav

私にとっての主な問題は、隠しフィールドに関するものでした。フォームを10〜15秒間ハングさせました。

非表示のフォームフィールドを画面の外に配置することで、なんとか回避できました。


隠れる:

position: absolute;
left: -9999px;

表示するには:

position: relative;
left: 0;

3
Simon McFarlane

同じfreezeing問題があります。

私たちが同じ状況にあるかどうかはわかりません。

ここに私のデモがあります: http://tedzhou.github.io/demo/ios7sucks.html

私のページでは、onclick属性を持つ<p>要素をbuttonとして使用しています。ユーザーがボタンをクリックすると、ページがtextareaに変わります。次に、それをクリックすると、ブラウザがフリーズします。

凍結時間は、dom要素の数に関連して費やされました。私のページには10000の要素があり、10秒以上フリーズします。

<p>要素を実際の<button>に切り替えるか、dom要素の数を減らすことで問題を解決できます。

pS:私の貧しい英語をごめんなさい。笑

3
tedzhou

私にとって、この問題は、ユーザー入力が_display:none_でページ上に隠されていることが原因でした。

私が使用した回避策:_display:none_で入力を非表示にする代わりに、jQueryのdetach()メソッドをドキュメントで使用して、使用されていないすべてのユーザー入力を「隠す」準備ができました。次に、必要なときに入力をappend()します。

これにより、ページが最初に読み込まれたときに入力に_display:none_がなかったため、最初のユーザー操作で遅延は発生しませんでした。

1
Dan Bamber

これはiOSだけでなく、Safari 7 for MAC OS(Maverics)でも発生します。フォーム内に入力(または選択)を含めるために多くのdivタグを使用すると、問題が発生することがわかりました。

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

Selectのレイアウトをdivの代わりにul/liとfieldsetsを使用するように変更し、フリーズ時間を大幅に削減しました。

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

次に、jsfiddleの2つの例を示します。

5秒間フリーズ

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

1秒間フリーズ

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

私はそれが誰かを助けるかもしれないと思います

1
Raphael Isidro

多くの入力を持つ非常に複雑なアプリケーションで同じ問題に遭遇しました。

USB経由でデバッガーをSafari iOS7に接続し、UIイベントをログに記録しました。 textarea(または任意の入力)をクリックするとすぐに「touchend」イベントが発生し、その後10〜20秒で「クリック」がディスパッチされるのがわかります。

AndroidまたはiOS6のような他のデバイスと同様、Safaryのバグであることは明らかですが、まったく同じアプリケーションで問題はありません。

1
c-smile

私の答えは少しメイントピックから外れているかもしれませんが、シナリオが「似ている」と感じたため、いくつかの検索を行った後、私はここにたどり着きました。

問題:

私の問題はiOSのロックアップのように感じられましたが、ページ上の他の要素がまだインタラクティブだったため、完全ではありませんでした。 <input type="search" />要素。フィールドをクリックしてもフォーカスされません。しかし、画面上で約4〜5回タップすると、最終的にはフォーカスを取得します。

追加情報:

私のプロジェクトはハイブリッドアプリです:iOSアプリ内のWebView。このサイトはTwitter Bootstrapで構築されています。

ソリューション:

たまたま、要素にautofocus属性を設定しました。私はそれを削除しようとしましたが、それはうまくいきました...フィールドをフォーカスさせるための連続したタップはもうありません。

0
EdwardM

多くの人がまだこの問題を抱えていることに気付いたので、私もこの問題に遭遇しました。

基本的に私の解決策は、要素をサーバー側で隠すことです。私のページはASP.NETなので、パネルを使用して入力でdivをラップし、これらのパネルをVisible falseに設定しました。このように、入力をクリックした場合、サファリはサーバー側に隠されているため、他のすべてのコントロールを表示できません。

もちろん、これをクライアントサイドのjqueryのように機能させたい場合は、自動ポストバックとupdatepanelがどこかに必要になります。このソリューションには努力が必要ですが、実際にサファリのバグを修正しようとするよりも優れています。

お役に立てれば。

0
misha130

iOS 12.1.1-2018年12月

これが私の場合に機能した簡単な修正です:

window.scrollTo(0,0) //入力フィールドの「ぼかし」イベントに添付

UXの点では理想的ではないかもしれませんが(特に多くのフィールドを持つフォームがある場合)、10秒以上のフリーズ時間よりも確実に優れています。

0
SC1000

私の会社でも同じまたは同様の問題がありました。多数のドロップダウンリストを表示し、ユーザーがドロップダウンをクリックしたときはいつでも、IOS 7はページを1〜2分間フリーズします。フリーズを解除すると、すべてが適切に機能します。その点を先に。

これはすべての入力タイプに影響しました。多数のドロップダウンが最初のロード時に実際に非表示になりました-ユーザーはドロップダウンの表示を開始します。ドロップダウンが表示されるまで-すべてが正常に機能します。それらが表示されるとすぐに、次の入力クリックは、正常に機能していた入力であっても、ブラウザーをフリーズさせます。

他の人が指摘しているように、IOS 7は、ユーザーが最初に入力と対話した後にDOM内の可視入力を解析するときに問題があるようです。要素の数または複雑さ、あるいはその両方がオプション/ DOMが高いほど、フリーズがより顕著になります。

最初のユーザーインタラクションでは常にフリーズするため、ドロップダウンのリストを表示するとすぐに、非表示のユーザーアクションを開始することを決定しました。透明なボタン(非表示にすることはできませんでした-"表示"する必要があります)を作成し、ユーザーがドロップダウンリストを開いたらすぐにクリックを開始しました。これにより、IOSがDOMの解析をより高速に開始できると考えましたが、実際には問題が完全に修正されていることがわかりました。

0
Henry Fieger