4

While trying to tweak some scrolling script to perform "jump to" links on some pages, I noticed that if you have a page with contains a hash tag in the URL, the behavior is different depending on the browsers when you press enter on the address bar, after the page is loaded.

For example, if you load a page with an has in the URL and then scroll away from the target element, I noticed that on Firefox and IE, if you put your cursor on the address bar and press enter, the page will move back to the HTML element having the same id attribute as the hashtag but the page will not be reloaded.

I also noticed that neither popstate nor hashchange events are triggered in such scenario. The scroll event will most likely be triggered but how can we know this is not the user scrolling but the browser reseting back its position?

Is there any was to detect this type of event in the browsers? Given this is outside the viewport I'm a bit curious. But I have a scenario where I would like to reposition the menu depending is the page is scrolling up or down.

To try to explain what I'm looking for:

  1. Page with hashtag #test and element <div id="test">
  2. Press F5, the page posisition itself right where the <div> is
  3. Scroll up or down
  4. Go on the address bar and press enter
  5. ---- Looking for an event to detect the previous action ---
  6. the page posisition itself right where the <div> is

Example in JSBin (open in Firefox):

http://jsbin.com/rifikereze/1/edit?html,js,output

Output:

http://output.jsbin.com/rifikereze/1#test2

  1. Open your console in Firefox
  2. Make sure in the Firefox setting you enable "persistent logs" to keep logs after page reloads
  3. Press F5 (you should see a console message "reloaded")
  4. Now try to move the page, put your cursor in the address bar and press enter
  5. You will see the page does not reload

How can we detect these events (other than scroll events)?

Make sure to use Firefox on Windows if trying to reproduce. It looks like other OSes have other behaviors.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Nicolas Bouvrette
  • 4,295
  • 1
  • 39
  • 53
  • there's the scroll event, and if it's a focusable elm getting hit by the fragment, that would probably fire onfocus. afaik, there's no built-in generic navigation event. – dandavis Apr 03 '17 at 00:56
  • @dandavis I'm looking for a way to identify that the scrolling was triggered from this context to avoid the menu bar from hiding for example. Also this is not triggered by anything in the viewport so I'm not sure I'm picturing how onfocus events could be used. – Nicolas Bouvrette Apr 03 '17 at 01:00
  • You could check if `.scrollTop()` is at same value as element position in `document`, or use `history`, see [Global Variable usage on page reload](http://stackoverflow.com/questions/29986657/global-variable-usage-on-page-reload/30144363?s=2|1.3570#30144363) – guest271314 Apr 03 '17 at 01:05
  • @guest271314 history doesn't seem to be impacted by this behavior. Also even if I use scrollTop, how do I know what triggered the scrolling? – Nicolas Bouvrette Apr 03 '17 at 01:07
  • 1
    @NicolasBouvrette if your code does the scrolling, of course you should know where in your code, otherwise it must be user who scrolls. – King King Apr 03 '17 at 01:08
  • You can set, get and read `history` `.state` property, if `$(window).scrollTop()`returns same value as position of element set at `css` at `.ready()`, the user would have previously navigated to a hash link, yes? – guest271314 Apr 03 '17 at 01:10
  • @King King in this case the browser does the scrolling using the anchor. I'm looking for a way to detect this event. – Nicolas Bouvrette Apr 03 '17 at 01:10
  • @guest271314 I'm not sure I'm following. It's not the use who will trigger the scrolling but the browser after a user pressed enter in the address bar. Unless I missed something, in this scenario no history event seems to be trigger and the history state doesn't seem to change either. – Nicolas Bouvrette Apr 03 '17 at 01:14
  • Yes, user action navigates to a URL, for example `http://example.org#abc`, check `$(window).scrollTop()` return value; if value is same as `#abc` offset from top of `document`, perform tasks. – guest271314 Apr 03 '17 at 01:18
  • @guest271314 the problem is this action doesn't happen on navigation. From what I can tell all this action looks like is any scroll event. But I'm looking for a way to dinstinguish this from other scroll events. I can easily idebtify a page load with a hash in the URL. I'm looking for a way to identify if a user press enter in the address bar which seems to simply scoll back to the element without reloading the page. – Nicolas Bouvrette Apr 03 '17 at 01:20
  • @NicolasBouvrette _"the problem is this action doesn't happen on navigation. From what I can tell all this actio looks like is any scroll event."_ Not sure what you mean? Where is `scroll` event dispatched? At `.ready()` handler, or at logic following calling `$.holdReady()`, check `.scrollTop()` of `$(window)`. _"I'm looking for a way to identify if a user press enter in the address bar which seems to simply scoll back to the element without reloading the page."_ What is "seems to"? `window` is reloaded when address bar is focused and user presses `Enter`, yes? – guest271314 Apr 03 '17 at 01:24
  • 1
    @guest271314 As I was trying to explain to seems to be a Firefox and IE behavior. When you are on a page with a hash in the URL, after the page is loaded, if you scroll on that page and go back in the address bar and press enter, the browser will reposition the page without reloading. Let me update the question to try to clarify this point. – Nicolas Bouvrette Apr 03 '17 at 01:29
  • if you want to know when the user jumps to a point by clicking a target link (with `href="#targetName"`) then just handle the onclick event of all those links. – King King Apr 03 '17 at 01:31
  • @KingKing I don't. I want to know when a user, already on a page with a hash in the URL, which scrolled away from the element, clicks back on the address bar and press enter. This cause the browser to scroll back to this element without reloading the page. – Nicolas Bouvrette Apr 03 '17 at 01:36
  • Could not reproduce page not reloading at plnkr http://plnkr.co/edit/ce6muH4FyS1opWkFmFlB?p=preview at firefox by either pressing `F5` or focus at address bar and pressing `Enter`. Can you update plnkr with `html`, `javascript` to reproduce issue? – guest271314 Apr 03 '17 at 01:45
  • @guest271314 I'm not sure I understand your example. I just did one here: http://output.jsbin.com/minaziteru/1 - Click on the link, then the address bar and press enter. If you don't get a popup if means the browser did not reload. I don't get any popup in Firefox. You can check the full example here: http://jsbin.com/minaziteru/edit?html,js,output – Nicolas Bouvrette Apr 03 '17 at 01:57
  • The page is being reloaded, see `console` at http://jsbin.com/visariziqu/1/edit?html,js,output – guest271314 Apr 03 '17 at 02:05
  • @guest271314 I actually added a better example in the question (http://output.jsbin.com/rifikereze/1#test2). I forgot alerts don't work using `beforeunload` events. Results are the same for me using 51.0.1 (32-bit) on Windows. I'm getting the exact same result in IE Edge. – Nicolas Bouvrette Apr 03 '17 at 02:09
  • @guest271314 I'm not sure exactly what you are doing/seeing but when I load your example, click the link, and then click my address bar and press enter I get no console output (in Firefox). In Chrome it reloads but the problem is that Chrome ignores the position on reload - that's a different issue. – Nicolas Bouvrette Apr 03 '17 at 02:13
  • At firefox 52 at *nix the page is reloaded at key press of both `F5` and `Enter` when address bar is focused, after clicking `a href="#test2"` element , which also reloads page. See `localStorage` variable incremented and logged at `console` at each `$(function(){})` call when `document` is loaded – guest271314 Apr 03 '17 at 02:16
  • 1
    @guest271314 I guess Windows is getting a different behavior, the variable doesn't increment on my end. Found move evidence here: http://stackoverflow.com/questions/39116398/behavior-of-enter-key-when-pressed-in-address-bar-with-url-containing – Nicolas Bouvrette Apr 03 '17 at 02:20
  • Have not used `*indows, ie in some time. Not sure if can help with verifiable possible solution. – guest271314 Apr 03 '17 at 02:23
  • 1
    @guest271314 Thanks for trying - I doubt there is any response to my answer. I was merely looking for a confirmation :) – Nicolas Bouvrette Apr 03 '17 at 02:24

1 Answers1

1

Given the lack of answer, my presumed answer is No.

There is no way to detect re-positioning of browsers using fragment identifiers (aka hash) in URLs and the address bar.

On top of this, browsers seems to have inconsistent behaviors:

  1. Firefox on Linux behave differently than on Windows (it reloads the page).
  2. Chrome seems to be ignoring re-positioning unless the page's position is set back to the top position before unloading.
  3. There seems to be no standard across browsers on whether the normal behavior is to reload or re-position.

The only safe way to detect fragment identifiers repositioning is when loading the page.

Nicolas Bouvrette
  • 4,295
  • 1
  • 39
  • 53