Переход к локальному фрагменту URL не изменяет историю браузера

Когда я включаю ссылку на раздел на странице — при клике на эту ссылку история браузера не обновляется. Нажатие кнопки «Назад» приводит к переходу со страницы, а не к возвращению на то место страницы, где определена ссылка.

Редактирование: К сожалению, в этом Discourse я не могу создать элемент с идентификатором, поэтому не могу продемонстрировать это здесь. Исходный код ниже — это то, что я хотел бы делать, но здесь это приведено только для иллюстрации и не влияет на суть моей проблемы:

<div id="link-target"></div>

*Этот раздел связан с ссылкой выше. Здесь нечего смотреть.*

Это, в общем-то, ожидаемо. Если вы нажмёте на ссылку на другой пост в той же теме, она тоже не добавляется в стек истории, и это полная ссылка без фрагментов, поэтому мы никогда не добавляем переходы внутри темы в историю.

Мне кажется, такое поведение крайне неожиданным :slight_smile:

Вот пример страницы без JavaScript. В Chromium при клике на эту ссылку вы переходите в конец страницы. Нажатие кнопки «Назад» возвращает вас в то место, откуда вы перешли. Это ожидаемое поведение, которое вы увидите на любом другом сайте, не сохраняющем историю таким образом.

<a href="#target">ссылка</a>

<div style="height:2000px"></div>

<div id="target">Привет</div>

Я предполагаю, что Discourse обрабатывает фрагменты URL с помощью JavaScript, прокручивая страницу к нужному месту, поэтому запись в историю должна выполняться явно.

@codinghorror высказал чёткое и окончательное мнение по этому вопросу здесь. Удивительно видеть столь категоричное мнение относительно изменения стандартного поведения веб-браузера. Честно говоря, я ещё не использовал Discourse для интенсивной навигации по темам, поэтому не могу полностью оценить очевидность его аргумента.

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

Вот пример того, где такое поведение вызывает проблемы:

https://meta.discourse.org/tos

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

Зачем вообще предоставлять оглавление?

Для тех сайтов, которые хотели бы поддерживать стандартную навигацию браузера, есть какие-либо предложения?

Я изучаю возможность патчинга поведения прокрутки к элементу, которое, как я подозреваю, стоит за этим, но начинаю практически без знаний о кодовой базе :slight_smile: Я доберусь до этого в конце концов, но если у кого-то есть какие-то подсказки, я буду признателен за помощь!

В зависимости от контекста, в котором вы будете использовать свои якоря, возможно, этот плагин оглавление будет полезен (и, на мой взгляд, он хорошо подойдёт для страниц Условий использования и Часто задаваемых вопросов)?
Пример здесь.

Я и не осознавал, что это меня беспокоило, пока вы не указали на это. Я часто пытался вернуться к тому месту, где я кликнул по ссылке в Discourse, но вместо этого оказывался на предыдущей странице. Очень раздражает. Я всегда списывал это на сочетание iOS-приложения, поскольку я использую его практически для всего, связанного с Discourse, и на ошибку пользователя.

Этот компонент оглавления действительно отлично реализован, и мы используем его на каждой странице документации — очень благодарны за проделанную работу!

Однако проблема навигации остаётся. При клике на ссылку в оглавлении история браузера не обновляется, поэтому при возврате назад пользователь покидает страницу.

Это действительно так. Было бы здорово исправить это, @Johani, но у меня есть ощущение, что это очень сложно. Возможно, стоит просто использовать pushState при клике на ссылку в оглавлении.

Я реализовал обходное решение (что, возможно, является корректным подходом к кастомизации сайта с точки зрения Discourse в отношении навигации по ссылкам) с помощью компонента темы. Это следует паттерну, используемому в DiscoTOC, где в сообщение добавляется маркер для запуска соответствующего поведения. Соответствующий код находится здесь.

Я считаю, что модификация DiscoTOC для использования фрагментов URL и истории браузера — хорошая идея. Это требует изменения подхода компонента к навигации, что не является незначительным изменением. DiscoTOC использует атрибуты данных для передачи целевых элементов вместо атрибутов href ссылок. Не предпринимается попытка отразить новое местоположение страницы в URL браузера (window.location).

Я думаю, что паттерн, который я использую выше, мог бы подойти для DiscoTOC, но это имеет более широкие последствия для этого компонента с учётом его текущего подхода.

Будьте осторожны с pushstate… вам, вероятно, нужно использовать replacestate.

В данном случае, я думаю, стоит использовать pushState. Цель — обеспечить возможность возврата к предыдущей позиции, что требует добавления записи в историю, так как событие предотвращено.

Вот почему внизу каждой записи TOS (в данном примере) раньше были небольшие ссылки «вернуться наверх»… :thinking: