React: autoFocus не работает с SSR в React 16

Созданный на 9 окт. 2017  ·  12Комментарии  ·  Источник: facebook/react

<input autoFocus /> работает на клиенте, но не при гидратации.

Это потому, что раньше это реализовывалось в JS как особый случай, но hydrateInstance не вызывает планирования эффекта фиксации, который может вызывать .focus() как finalizeChildren .

Вопрос здесь в том, стоит ли нам вообще беспокоиться о реализации этого в JS или мы должны просто выдать атрибут autofocus в SSR и позволить браузеру позаботиться об этом.

Server Rendering Bug

Самый полезный комментарий

Первоначальной причиной отказа от использования атрибута autofocus было то, что реализации браузеров были в значительной степени непоследовательными в том, как они относились к нему (некоторые не поддерживают, некоторые фокусируются только на загрузке страницы и т. Д.). Что IMHO означает, что любой, кто серьезно относится к автофокусу, в любом случае должен был применить его вручную через JS. Однако я смутно припоминаю, что сейчас существуют мобильные браузеры, которые на самом деле не слушают фокусировку JS, но в некоторой степени поддерживают автофокусировку.

Это беспорядок, но есть некоторые достоинства в том, чтобы просто генерировать атрибут, и если вы чувствуете это сильно, вы фокусируетесь вручную. Вам даны все инструменты.

Все 12 Комментарий

Я думаю, нам следует использовать автофокус как атрибут.

Похоже, что ключевым недостатком является то, что autofocus не поддерживается в IE9, iOS Safari и браузере Android . Есть ли еще какие-то недостатки, которых мне не хватает? Насколько сложно / механически было бы добавить автофокус через JS?

Если мы всегда делаем это на JS, это довольно просто, но для семантики это плохо. Для загрузки всех скриптов может потребоваться некоторое время, прежде чем они действительно сфокусируются. Тем временем пользователь может сосредоточиться на других вещах, а затем внезапно он становится сосредоточенным. Поскольку с Fiber мы можем асинхронно регидратировать, и мы также можем захотеть сделать частичную гидратацию, это может сделать это даже хуже, чем сейчас.

Мы можем сделать и то, и другое, но тогда у вас будут странные артефакты, на которых он может сфокусироваться, вы выключаете его, а затем он снова фокусируется.

Мы потенциально могли бы сделать это в JS только в случае сбоя обычного, но не знаем, как это обнаружить, и это может добавить много кода.

Я не уверен, какой компромисс здесь правильный, учитывая проблему поддержки браузера.

Для загрузки всех скриптов может потребоваться некоторое время, прежде чем они действительно сфокусируются.

Я думаю, что это очень веский аргумент в пользу создания атрибута. Похоже, мы не можем гарантировать правильность, даже если мы проверим document.activeElement , возможно, пользователь уже находится в потоке или прокручивает страницу вниз. Мы не хотим, чтобы страница подскочила или кто-то начал вводить текст в другое поле ввода в середине нажатия клавиши.

Извините, если что-то из этого является перефразированием, но это был бы аргумент, который я бы выдвинул, если бы кто-то подал вопрос об этом.

Атрибут испускания звучит как правильный путь. Если я хочу, чтобы автофокус работал в браузерах, которые его не поддерживают, разумнее всего добавить скрипт в конец тела:

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

Что, я думаю, вызывает проблемы только в том случае, если HTML-страница очень большая. Я предполагаю, что он также может проверить наличие activeElement (если нет или тело, тогда фокус), но это может быть излишним.

Первоначальной причиной отказа от использования атрибута autofocus было то, что реализации браузеров были в значительной степени непоследовательными в том, как они относились к нему (некоторые не поддерживают, некоторые фокусируются только на загрузке страницы и т. Д.). Что IMHO означает, что любой, кто серьезно относится к автофокусу, в любом случае должен был применить его вручную через JS. Однако я смутно припоминаю, что сейчас существуют мобильные браузеры, которые на самом деле не слушают фокусировку JS, но в некоторой степени поддерживают автофокусировку.

Это беспорядок, но есть некоторые достоинства в том, чтобы просто генерировать атрибут, и если вы чувствуете это сильно, вы фокусируетесь вручную. Вам даны все инструменты.

Я поговорил об этом с @trueadm, и я думаю, что это звучит как правдоподобный путь вперед:

Реагировать 16

  • Отправьте его в SSR HTML.
  • Убедитесь, что мы не вызываем JS-полифил для гидратированных элементов.
  • Сохраняйте его в черном списке для созданных клиентом элементов и используйте для них полифилл JS.

Реагировать 17

  • Полностью удалите JS-полифилл.
  • Предупреждать, если во время фиксации добавлено более одного элемента autoFocus (поскольку именно здесь возникают несоответствия браузера).

Имеет ли это смысл?

Предупреждать, если во время фиксации добавлено более одного элемента autoFocus (поскольку именно здесь возникают несоответствия браузера).

Браузеры, по крайней мере, недавно, также непоследовательно интерпретируют атрибут autoFocus. Я знаю, что, например, FF будет учитывать его только при загрузке страницы и полностью игнорировать все, что было динамически вставлено. Но я уже давно не исследовал его.

Тем не менее, я считаю, что подход правильный.

После некоторого базового исследования похоже, что большинство современных браузеров, за исключением Safari, вообще не уважают autoFocus после загрузки страницы.

Вероятно, это имело смысл для HTML-документов, но в приложениях я ожидал, что autoFocus будет соблюдаться для динамически вставляемых элементов, поскольку они в основном являются «переходами страниц» в той же степени, что и загрузка первой страницы в SPA.

Так что, вероятно, нам следует оставить полифилл.

Становится еще более странным.

Chrome учитывает динамически добавляемые элементы с autoFocus если их раньше не было. Даже создания ввода с помощью autoFocus , добавления его в документ и удаления его в следующем тике достаточно, чтобы отключить автофокусировку любых элементов, добавленных в будущем в Chrome.

Firefox просто не заботится о каких-либо динамически добавляемых элементах с autoFocus .

И Safari всегда их уважает.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги