React: autoFocusはReact16のSSRでは機能しません

作成日 2017年10月09日  ·  12コメント  ·  ソース: facebook/react

<input autoFocus />はクライアントで機能しますが、ハイドレイトされている場合

これは、これが特別な場合としてJSに実装されていたためですが、 hydrateInstanceは、 finalizeChildrenように.focus()呼び出すことができるコミット効果をスケジュールしません。

ここでの問題は、これをJSで実装する必要があるのか​​、それともSSRでautofocus属性を発行して、ブラウザーに処理させるのかということです。

Server Rendering Bug

最も参考になるコメント

autofocus属性を発行しない最初の理由は、ブラウザーの実装がそれをどのように処理するかについて広く一貫性がなかったためです(サポートしないもの、ページの読み込みのみに焦点を合わせるものなど)。 これは、オートフォーカスを真剣に考えている人は、とにかくJSを介して手動で適用する必要があることを意味します。 ただし、JSフォーカスを実際にはリッスンしないが、ある程度オートフォーカスを尊重するモバイルブラウザが存在することを漠然と覚えています。

面倒ですが、属性を出力するだけでもメリットがあり、強く感じたら手動で集中します。 すべてのツールが提供されます。

全てのコメント12件

属性としてオートフォーカスを出すべきだと思います。

主な欠点は、IE9、iOS Safari、およびAndroidブラウザ

常にJSで行う場合、それは非常に簡単ですが、セマンティクスにはかなり悪いようです。 すべてのスクリプトが実際にフォーカスされるまでにロードされるまで、しばらく時間がかかる場合があります。 その間にユーザーは他のものに焦点を合わせることができ、その後突然焦点が合うようになります。 ファイバーを使用すると、非同期で水分補給が可能であり、部分的な水分補給も必要になる場合があるため、これは以前よりもさらに悪化する可能性があります。

両方を行うことはできますが、焦点が合う可能性のある奇妙なアーティファクトがあり、スイッチをオフにすると、再び焦点が合います。

通常のJSで失敗した場合にのみ、JSでそれを実行できる可能性がありますが、それを検出する方法がわからないため、多くのコードが追加される可能性があります。

ブラウザのサポートの問題を考えると、ここで正しいトレードオフが何であるかはわかりません。

すべてのスクリプトが実際にフォーカスされるまでにロードされるまで、しばらく時間がかかる場合があります。

これは、属性を発行するための非常に強力なケースだと思います。 document.activeElementをチェックしても、ユーザーがすでにフローに入っているか、ページを下にスクロールした可能性がありますが、正確性を保証できないようです。 ページがジャンプしたり、キーストロークの途中で誰かが別の入力ボックスに入力し始めたりすることは望ましくありません。

その一部が再ハッシュである場合は申し訳ありませんが、誰かがそれについて問題を提起した場合、それは私がする議論になるでしょう。

属性を出力するのは正しい方法のように思えます。 オートフォーカスをサポートしていないブラウザで動作させたい場合は、本文の最後にスクリプトを追加するのが最も賢明なようです。

    <script>!function(el){el&&el.focus()}(document.querySelector('[autofocus]'))</script>

これは、HTMLページが非常に大きい場合にのみ問題を引き起こすと思います。 activeElementをチェックすることもできると思います(何もないか、bodyの場合はフォーカスします)が、それはやり過ぎかもしれません。

autofocus属性を発行しない最初の理由は、ブラウザーの実装がそれをどのように処理するかについて広く一貫性がなかったためです(サポートしないもの、ページの読み込みのみに焦点を合わせるものなど)。 これは、オートフォーカスを真剣に考えている人は、とにかくJSを介して手動で適用する必要があることを意味します。 ただし、JSフォーカスを実際にはリッスンしないが、ある程度オートフォーカスを尊重するモバイルブラウザが存在することを漠然と覚えています。

面倒ですが、属性を出力するだけでもメリットがあり、強く感じたら手動で集中します。 すべてのツールが提供されます。

私はこれについてましたが、これはもっともらしい方法のように聞こえると思います。

React 16

  • SSRHTMLで出力します。
  • 水和要素に対してJSポリフィルと呼ばないようにしてください。
  • クライアントが作成した要素でブラックリストに登録し続け、それらにはJSポリフィルを使用します。

React 17

  • JSポリフィルを完全に削除します。
  • コミット中に複数のautoFocus要素が追加された場合に警告します(これはブラウザーの不整合が発生する場所であるため)。

これは意味がありますか?

コミット中に複数のautoFocus要素が追加された場合に警告します(これはブラウザーの不整合が発生する場所であるため)。

ブラウザーは、少なくとも少し前までは、autoFocus属性の解釈方法にも一貫性がありません。 たとえば、FFはページの読み込み時にのみそれを尊重し、動的に挿入されたものは完全に無視することを私は知っています。 しかし、私は長い間それを調査していません。

それでも、アプローチは正しいと思います。

いくつかの基本的な調査の結果、Safariを除くほとんどの最新のブラウザautoFocus 、ページの読み込み後に

HTMLドキュメントの場合はおそらく理にかなっていますが、アプリでは、動的に挿入された要素は基本的にSPAの最初のページの読み込みと同じくらい「ページ遷移」であるため、 autoFocusが尊重されると思います。

したがって、おそらくポリフィルを保持する必要があります。

それはより奇妙になります。

Chromeは、動的に追加された要素がautoFocusなかった場合、それを尊重します。 autoFocusを使用して入力を作成し、それをドキュメントに追加し、次のティックで削除するだけでも、Chromeで将来追加される要素のオートフォーカスを無効にするのに十分です。

Firefoxは、 autoFocusで動的に追加された要素をまったく気にしません。

そしてSafariは常にそれらを尊重します。

このページは役に立ちましたか?
0 / 5 - 0 評価