ローカル URL フラグメントへの移動はブラウザの履歴を変更しない

ページ内のセクションへのリンク を含めると、そのリンクをクリックしてもブラウザの履歴が更新されません。戻る操作を行うと、ページ自体を離れてしまい、リンクが定義された位置に戻ることはできません。

編集:この Discourse では ID を持つ要素を作成できないため、ここでデモを表示することはできません。ここで示しているソースコードは、私が実現したい動作です。ただし、これは単なる例示であり、私の問題の本質には影響しません。

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

*このセクションは上記からリンクされています。見るべきものはありません。*
「いいね!」 1

これはある程度予想通りです。同じトピック内の別の投稿へのリンクをクリックしても、それは履歴スタックに追加されず、フラグメントのない完全なリンクとなるため、トピック内への移動は履歴に追加されません。

「いいね!」 1

この挙動は非常に予想外です :slight_smile:

ここに JavaScript のないサンプルページがあります。Chromium でそのリンクをクリックすると、ページの下部に移動します。戻るボタンをクリックすると、クリックした場所に戻ります。これは、この履歴を消費しない他のすべてのウェブサイトで見られる、期待される挙動です。

<a href="#target">link</a>

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

<div id="target">Hello</div>

Discourse は JavaScript で URL フラグメントを処理し、その場所にスクロールしているため、履歴を明示的にプッシュする必要があると推測します。

@codinghorrorこちら で、これについて強くかつ最終的な意見を述べています。標準的なウェブブラウザの挙動の変更に対して、これほど強い意見が表明されているのは驚きです。公平を期すために言いますが、私はまだ Discourse を本格的なトピックナビゲーションに使用していないため、彼の主張の明瞭さを十分に理解できていません。

私は ドキュメント としても Discourse を利用していますが、この挙動は非常に混乱を招くもので、リンクをクリックするとページ上の現在位置を失ってしまうのではないかと恐れています。

「いいね!」 1

この挙動が問題となる例を以下に示します:

https://meta.discourse.org/tos

目次リンクのいずれかをクリックした後、ブラウザの履歴を使って元の場所に戻ろうとしても、それができません。

そもそもなぜ目次を提供するのでしょうか?

標準的なブラウザのナビゲーションをサポートしたいサイトに対して、何か提案はありますか?

私はこの背後にあると疑われる「要素へスクロールする」挙動をモンキーパッチで修正しようと考えていますが、コードベースについては全くの初心者です :slight_smile: 最終的には解決するつもりですが、もし何かヒントがあれば、助けていただければ幸いです!

「いいね!」 1

アンカーを使用する文脈によっては、この 目次 プラグインが役立つかもしれません(個人的には、利用規約やよくある質問ページに合うと思います)。例は こちら です。

「いいね!」 1

あなたが指摘するまで、それが私を悩ませていたことに気づきませんでした。Discourse でリンクをクリックした場所に戻ろうとして、以前ページに戻ってしまうことがよくありました。とてもイライラします。私はいつも、iOS アプリ(Discourse のほぼすべての操作で使っているため)とユーザーの誤操作の組み合わせだと片付けていました。

「いいね!」 1

この目次コンポーネントは非常に良く作られており、すべてのドキュメントページで使用しています。この取り組みに心から感謝しています!

ただし、ナビゲーションに関する問題は残っています。目次のリンクをクリックしてもブラウザの履歴が更新されないため、戻る操作をするとページ外に移動してしまいます。

「いいね!」 1

確かにその通りです。@Johani さん、これを修正できれば素晴らしいのですが、かなり複雑な問題のような気がします。目次のリンクをクリックしたときに pushstate を実行するだけでも良いかもしれません。

「いいね!」 5

サイトのカスタマイズについて、Discourse のリンクナビゲーションに関する見解を踏まえた(議論の余地はありますが)適切なアプローチとして、テーマコンポーネントを用いた回避策を実装しました。これは、DiscoTOC が採用しているパターンに倣っており、投稿にマーカーを追加して動作をトリガーするものです。該当するコードはこちらです。

DiscoTOC を URL フラグメントとブラウザの履歴機能を使用するように変更するのは良いアイデアだと思います。ただし、これにはコンポーネントのナビゲーションアプローチの変更が必要であり、軽微な変更ではありません。DiscoTOC は、リンクの href 属性ではなく、データ属性を使ってターゲットを渡しています。また、ブラウザの URL(window.location)に新しいページ場所を反映させる試みは行われていません。

上記で示したパターンが DiscoTOC でも機能する可能性がありますが、そのコンポーネントの現在のアプローチを考えると、より広範な影響を及ぼすことになります。

「いいね!」 2

そこでの pushstate には注意してください。おそらく必要なのは replacestate です。

この場合は pushState だと思います。イベントが防止されているため、履歴にプッシュすることで、前の位置に戻ることを可能にするのが目的です。

そのため、(この例に合わせて)各利用規約の項目の下部には、かつて「トップへ戻る」の小さなリンクが設置されていたのです… :thinking: