Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is changing hash not affecting length of history?

Tags:

javascript

Consider this snippet:

console.log( "1st", history.length );

location.hash = location.hash + "some-value";

console.log( "2nd", history.length );

setTimeout( function() {

  console.log( "3rd", history.length );

  history.back();

  console.log( "4th", history.length );

}, 1000 );

https://jsfiddle.net/1kqLofq4/2/

I'm curious about why changing hash isn't adjusting length of history but using history.back() is required to revert that change of hash? I have tested this scenario with Firefox 46 and Chrome 49. Output is always similar to this:

1st 17
2nd 17
3rd 17
4th 17

I've tried searching for some specs or information on this case, why this might be intended behaviour and how I could detect change in history like this using some other information than history.length. But all I got was hints on using some fancy framework plugins I'm definitely not interested in.

like image 497
Thomas Urban Avatar asked Apr 28 '16 18:04

Thomas Urban


1 Answers

I may be misunderstanding, but the specification doesn't seem to support this behaviour. It may be a bug.

From step 6 in section 7.8.1: Navigating across documents of the WHATWG HTML Specification.

  1. Fragments: If this is not a reload-triggered navigation: apply the URL parser algorithm to the absolute URL of resource and the address of the active document of browsingContext; if all the components of the resulting URL record, ignoring any fragment components, are identical, and resource is to be fetched using GET, and the URL record of resource has a fragment component that is not null (even if it is empty), then navigate to that fragment and abort these steps.

From section 7.8.9 Navigating to a fragment:

  1. Append a new entry at the end of the History object representing the new resource and its Document object, related state, and current history scroll restoration preference. Its URL must be set to the address to which the user agent was navigating. The title must be left unset.

I didn't see anything about replacing the history entry in some way instead of modifying it if it's just a fragment change. The behaviour of .length and .back() are both supposed to refer to the same set of history entries (the combined "joint session history"), so it seems like they shouldn't exhibit an inconsistency like this. From the Notes in this section:

window.history.length

Returns the number of entries in the joint session history.

window.history.back()

Goes back one step in the joint session history.

like image 68
Jeremy Avatar answered Sep 22 '22 15:09

Jeremy