Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Scenario A)
Following URLs pointing to fragments on the current page causes a full page reload before locating the fragments..
E.g. while on page www.example.com/pageA clicking www.example.com/pageA#Section1 cause a full page reload and then take you to Section1.
Scenario B)
Following URLs pointing to fragments on different pages fail to load. An ajax error is output in the browser log.
E.g. while on page www.example.com/pageA clicking www.example.com/pageB#Section2 appears to do nothing and creates a browser Ajax error.
Last checked against Version: 8x-1.0-alpha2+7dev
Comment | File | Size | Author |
---|---|---|---|
#20 | 2705363-20.patch | 13.56 KB | Wim Leers |
Comments
Comment #2
serg2 CreditAttribution: serg2 commentedComment #3
serg2 CreditAttribution: serg2 commentedComment #4
Wim LeersBy "anchor links", do you mean things like
<a href="#heading-to-jump-to">Go to X</a>
? I've known them to be called "jump links" or "fragment links" or just "fragments", but never "anchor links". Just verifying :)Comment #5
serg2 CreditAttribution: serg2 commentedYes, that is what I meant.
I think "fragment identifier" is the official name for the "#example" bit and the anchor is the Id it links to. (https://www.w3.org/TR/html401/intro/intro.html#fragment-uri).
I should have made the issue clearer. If the URI is on the same page it works as normal. Where the URI refers to a specific location on a different page then the link is broken.
Comment #6
Wim LeersAha! That helps :)
Comment #7
Wim LeersComment #8
Wim LeersThe notice in the IS was due to #2692317-17: Make everything in <head> update: <title>, <meta> tags, etc.. Fixed that in that issue. But this issue is still relevant: any fragment link on the current page causes the entire page to be reloaded needlessly, due to RefreshLess's
onpopstate
event handler.Please confirm in the mean time that with HEAD, that's indeed the only remaining problem with fragment URLs.
Comment #9
serg2 CreditAttribution: serg2 commentedI have done more testing this morning and this comment appears incorrect, please see next comment.
Against head (Version: 8.x-1.0-alpha2+5-dev):
Links with URL fragments pointing to destinations on the current page work perfectly.
Links with URL fragments pointing to destinations on different pages do not work. Clicking them appears to do nothing in the browser. They produce an Ajax Error.
That is the only problem I can find with URL fragments.
Comment #10
serg2 CreditAttribution: serg2 commentedWith head (Version: 8.x-1.0-alpha2+5-dev)
Scenario A)
URL Fragments pointing to locations on the current page cause a full page reload and then finds the correct location.
E.g. while on page www.example.com/pageA clicking www.example.com/pageA#Section1 cause a full page reload and then take you to Section1.
Scenario B)
Links with URL fragments pointing to locations on different pages fail to load. An ajax error is output in the browser log.
E.g. while on page www.example.com/pageA clicking www.example.com/pageB#Section2 appears to do nothing and creates a browser Ajax error.
Could someone else please reproduce the result of Scenarios A & B.
Comment #11
serg2 CreditAttribution: serg2 commentedComment #12
serg2 CreditAttribution: serg2 commentedComment #13
Wim LeersConfirmed both. On this now.
Many thanks for #9 + #10, that was very helpful!
Comment #14
Wim LeersI first had to do #2713439: Allow navigating back to the original page without doing a full reload, because thanks to this issue, I started to see how having a cohesive, comprehensive way to deal with the state at each History position would make solving this issue simpler.
Comment #15
Wim LeersHere is my super rough, super naïve solution.
It works… as long as you don't use the backward/forward buttons. Then it completely breaks. That's of course not acceptable.
Comment #16
Wim LeersThe reason #15 doesn't work, is because it doesn't track state for fragment-based navigation.
Specifically, if you navigate like this:
… then the corresponding history entries look like this:
… because #15 leaves the fragment-based navigation to the browser.
What's the problem then? Well, if you go back from
/bar
to/foo#llama
, the browser will just scroll back to the position that#llama
was in, but it will not restore the content for/foo
!So, what we need is:
Drupal.refreshless.state.1 -> Drupal.refreshless.state.2 -> Drupal.refreshless.state.3
As you can imagine, this is easier said than done. The biggest hurdle is the fact that the History API
PopStateEvent
does not tell you what the state is you're coming from. Not even the position. So we have to track this outside the History API.In other words: the History API is poorly designed. It's good that it's restricted, but it is too restricted. Which is exactly why almost nobody in the world seems to have ever attempted this: 99% of examples are crappy, silly, simple: they simply perform an AJAX request on every page load.
Comment #17
serg2 CreditAttribution: serg2 commentedTested this against the current dev(which has #2713439: Allow navigating back to the original page without doing a full reload applied) and works as you described with the issues you described. Also, the changes you made to the loading of the libraries seem great.
Comment #18
Wim LeersThis took me several days to figure out! (Including the explanation in #16.)
Comment #19
Wim LeersI think it's fair to say this is critical, actually. Some sites heavily rely on fragment navigation, and without this, it'd be painfully broken.
Comment #20
Wim LeersLet's document this at a very high level, to allow people to understand roughly how this all works without having to read the code.
Comment #21
Wim LeersAfter thorough manual testing and having worked on this for many days, I think this is ready. Any remaining problems should be reported as new issues.
Comment #22
Wim LeersComment #23
Wim LeersFollow-ups that I discovered while working on this: