{
  "attributes": {
    "id": "scroll-targeting",
    "linkText": "Scroll Targets",
    "title": "Automatic Scrolling and Click To Copy Headers",
    "group": "Architecture"
  },
  "body": "<p>Fountainhead has different automatic scrolling to header and property ids for <em>Hash\nLocation</em> consumers and <em>History Location</em> consumers. The goal of this is to offer very\nclean URLs for consumers using history location routing, while still supporting targeted\nscrolling for consumers using hash location routing. History routing consumers will\ngenerate URLs with fragment ids. Hash routing consumers will generate URLs with <code>id</code>\nquery params:</p>\n<p><strong>History Location Routing:</strong><br/>\n<code>your-docs.com/guides/your-guide#header-id</code><br/>\n<strong>Hash Location Routing:</strong><br/>\n<code>your-docs.com/#/guides/your-guide?id=header-id</code></p>\n{{#fountainhead-header tagName=\"h2\" elementId=\"feature-overview\"}}Feature Overview{{/fountainhead-header}}\n<p>If you need to make an update or log a bug against the feature this overview will\nprovide background information on how the overall flow executes.</p>\n<ol>\n<li>Addon <code>index.js</code> reads consuming application's <code>locationType</code> in addon <code>config</code>\nhook. The <code>locationType</code> is passed into every call to generate documentation data.\nIn data generation, if the <code>locationType</code> is <code>hash</code>, the flag <code>hashRouting</code> is\nset to true and added to the documentation meta. <em>(History routing is the\ndefault routing expected. hashRouting is only set as an override)</em></li>\n<li>Addon begins tracking the location hash in order to pass the hash down as a data\nelement. Routes <code>/api</code> and <code>/guides</code> activate hook trigger the <code>fountainhead</code>\nservice to set an event listener for the <code>hashchange</code> event. This event fires\nanytime an in page url with a hash fragment is clicked. All routes will reset the\ntracked fragment id and then update it after the url changes <em>(Required due to\nroute changes not firing the hashChange event)</em>.</li>\n<li>Routes will reset the page scroll to the top on every transition. This ensures\nthat if the page is scrolled, and the new route doesn't have a scroll target, the\npage is correctly scrolled to the top.</li>\n<li>Page templates pass either the tracked hash fragment or the controller <code>id</code> query\nparam to page components depending on the consuming routing type.</li>\n<li>Any change in the model or passed scroll target will trigger the page's\n<code>didReceiveAttrs</code> hook, which is used to scroll to the passed target, or scroll to\ntop of page if no target is present.</li>\n<li>Headers and property links are wrapped in either an anchor with the href set to a\nfragment id for history location consumers or a <code>link-to</code> with the id query param\nfor hash location users.</li>\n</ol>\n{{#fountainhead-header tagName=\"h2\" elementId=\"feature-overview-ii\"}}Feature Overview II{{/fountainhead-header}}\n<ol>\n<li>Addon checks if consumer is using Hash or History location, updates Fountainhead's\ndocumentation meta with flag.</li>\n<li>IF HASH =&gt; Use query params, and everything will Just Work™. Router, link-tos and\ncontrollers automatically track <code>id</code> query param. Passed down into page components\nwe can use <code>didReceiveAttrs</code> hook to execute scrolling.</li>\n<li>IF HISTORY =&gt; Hash has to be tracked:\n<ul>\n<li>Ember will leave fragment ids in urls on page reload</li>\n<li>Anchors with ONLY fragment ids do not trigger Ember route changes, url updates\nwith new hash (hashChange event fires) (this is 👍 for copyable headers and\nproperty links in class page index tab)</li>\n<li>Link-tos (even with forced hash addition) have hash stripped from url at some\npoint. (this is a problem for cross-link)</li>\n</ul>\n</li>\n<li>On route activation, send <code>trackHash</code>, creates new listener for hash change AND\nsets current hash if one has been set (this is how page reload still triggers a\na scroll).</li>\n<li>Clicking an anchor with fragment ONLY will fire a hash change event, but clicking\na link-to to a different route OR clicking browser back button will NOT fire a\nhash change event.</li>\n<li>For route changes:\n<ul>\n<li>Default behavior is to update the tracked fragment using <code>scheduleOnce</code> <code>render</code>\nqueue. At that time the url is updated. (When clicking the back button, the url\nat this point may have a previous scroll target.)</li>\n<li>For cross-links pointing to some target, Ember strips out the fragment during\ntransition. Cross-links handle this by looking up current route and setting a\n<code>crossLinkFragmentOverride</code> on click of a cross link. Then in the <code>scheduleOnce</code>\nhandler we can check for the fragment override to know that there SHOULD be a\nfragment in the url. (this is the navigating forward with hash scenario).</li>\n</ul>\n</li>\n</ol>\n",
  "frontmatter": "id: scroll-targeting\nlinkText: Scroll Targets\ntitle: Automatic Scrolling and Click To Copy Headers\ngroup: Architecture",
  "id": "scroll-targeting",
  "type": "guides"
}