EmberJS でリンクのアンカーを機能させる


すべての Web アプリは URL で始まります.また、Web アプリで一般的に使用される URL は通常、次のようになります.

https://domain.com/path?query=value#fragment


最後のビット ( fragment ) を instruct the browser に使用して、上記のフラグメントと同じ id を持つ要素にページをスクロールできます.これらは通常、アンカーまたはページ内アンカーと呼ばれます.例:

<!-- <a> element links to the section below -->
<p><a href="#Section_further_down">
  Jump to the heading below
</a></p>

<!-- Heading to link to -->
<h2 id="Section_further_down">Section further down</h2>


スクロールは、ユーザーが現在のページのリンクをクリックしたとき、およびユーザーがブックマークや他のアプリから URL を開いたときにも機能します.

問題



残念ながら、Single-page applications (SPA) の出現により、ブラウザのこの気の利いた機能が機能しなくなりました.

なんで?最初は、SPA には大きな JavaScript バンドルへのリンクを含む最小限の HTML があり、最終的にブラウザーによって解析され、JS コードが URL、データ、コード ロジックなどに基づいてそれぞれの要素を DOM に入力するためです.

そのため、ブラウザが URL のフラグメントと同じ ID を持つタグの存在を DOM でチェックインするとき、DOM はほとんど空であるため、ブラウザは何も検出しません.

ソリューション



幸いなことに、 EmberJS にはアドオン ( ember-url-hash-polyfill ) があり、まさにこの種の問題を非常にエレガントな方法で解決します.アドオンの README から:

Navigating to URLs with #hash-targets in them is not supported by most single-page-app frameworks due to the async rendering nature of modern web apps -- the browser can't scroll to a #hash-target on page load/transition because the element hasn't been rendered yet.

This addon provides a way to support the behaviour that is normally native to browsers where an anchor tag with href="#some-id-or-name" would scroll down the page when clicked.



インストールしたら:

ember install ember-url-hash-polyfill


アプリ router.js を調整し、 withHashSupport デコレーターを追加するだけです.

// app/router.js

import { withHashSupport } from 'ember-url-hash-polyfill';

@withHashSupport
export default class Router extends EmberRouter {
  location = config.locationType;
  rootURL = config.rootURL;
}


その後、ページ内アンカーを含むすべての URL が機能するはずです™.


Lucas SankeyUnsplashによる写真