choojs / choo

:steam_locomotive::train: - sturdy 4kb frontend framework
https://choo.io/
MIT License
6.78k stars 595 forks source link

Page anchors ignored #666

Closed jongacnik closed 6 years ago

jongacnik commented 6 years ago

Expected behavior

When an anchor tag with a hash route is clicked, <a href="#page-anchor">Jump To</a>, the page should first be checked to see if an available page anchor exists and update scroll. Only if a page anchor is not found should a route change be triggered. Basing this off of https://github.com/choojs/choo#hash-routing and https://choo.io/docs/routing

Actual behavior

Route change is always triggered and no jump-to behavior is possible

Example

demo: https://choo-hash-bug.glitch.me/ code: https://glitch.com/edit/#!/choo-hash-bug?path=index.js:17:23

Curious if anyone else has ran into this? ✌️

toddself commented 6 years ago

This is expected behavior.

From the https://choo.io/docs/routing page:

Navigating to External Links

Some links in your app will point to other pages. In order to do this safely, we must add some attributes to our link tags. This is needed, so the pages we link to can't hijack our page.

In order to link to an external link, we must do one of the following:

   *  the click event had .preventDefault() called on it
   * the link has a target="_blank" attribute with rel="noopener noreferrer"
   * a modifier key is enabled (e.g. ctrl, alt, shift or meta)
   * the link's href starts with protocol handler such as mailto: or dat:
   * the link points to a different host
   * the link has a download attribute

You'll need to do one of those things in order to get choo to stop routing on that link.

(Please re-open this issue if you're still experiencing problems!)

jongacnik commented 6 years ago

Gonna re-open this one since this functionality is actually meant to be supported. From the choo docs:

Page Anchors

Another use of hashes in urls is to map to anchors on the page. This is commonly used for headings in articles. So when a link is shared, they're navigated to the right heading in the page.

Choo supports page anchors out of the box. It tries to match anchors on the page first. If no matching anchor is found, Choo will try to find a matching route in the router. If no matching route is found, the regular fallback behavior occurs, such as navigating to a 404 route.

That said, sounds like this functionality never actually got built-out: scroll down to Clicking Anchors.

tornqvist commented 6 years ago

I've ran in to this a couple of times, usually resolved it by adding a route for capturing anchors:

app.route('/pages/:anchor', require('./pages-listing-or-single-page'))

But that means that I can only support hash anchors at one level and they'd conflict with other path partials. E.g. this is what I'd like to do but it would totally not work (due to conflicting routes and multiple wildcards) but it'd be neat to support anchors at any and all routes without hacks:

app.route('/pages/:anchor', require('./pages-listing')) // -> /pages#page01-heading
app.route('/pages/:page', require('./singe-page')) // -> /pages/page01
app.route('/pages/:page/:anchor', require('./singe-page')) // -> /pages/page01#heading

IMO hash routing is an edge case only applicable for legacy browsers and for mounting the application at a path instead of site root, and should therefore be opt-in.

jongacnik commented 6 years ago

@tornqvist Ya I had ended up doing the same in my app, luckily there was no conflicting sub-route.

While it's interesting for the router to support both hash and non-hash together, not totally sure when you'd really need it, and even the dox discourage it:

Using both hashes in URLs and anchor links on the page is generally not recommended.

opt-in hash routing seems like a decent move to me too!

bennlich commented 4 years ago

As far as I can tell, the behavior described in the docs (to scroll to a matching id if it exists, otherwise route) is still not what happens. I've opted into hash routing, and my hash links are not working as anchors.

EDIT: Which is strange, because this example seems to work: https://choo-hash-anchors-enabled.glitch.me/my/app#footer. I'm on choo 7.0

tornqvist commented 4 years ago

As stated in readme (https://github.com/choojs/choo#hash-routing)

Using both hashes in URLs and anchor links on the page is generally not recommended.

The linked example actually exemplifies how it doesn't work. Regardless of what path you're on, when kicking on the #footer anchor tag you're not just scrolled to the bottom of the page but also navigated to /my/app/footer.