history.js icon indicating copy to clipboard operation
history.js copied to clipboard

No statechange event when both path and hash are changed via pushState

Open mcjahudka opened this issue 12 years ago • 9 comments

Hello,

I believe I found a bug in history.js. When you push a state that changes both the path and the hash part of the location, no statechange event is triggered.

Fiddledydoo: http://jsfiddle.net/yBN6j/

mcjahudka avatar Sep 23 '13 14:09 mcjahudka

Additional info:

  • the fiddle doesn't work in opera 12.16, for some reason jQuery 1.10.1 throws a security exception; when jQuery is switched to version 1.9.1 the fiddle runs okay, but the issue is still present
  • firefox 23.0.1 has this problem as well
  • chrome 29.0.1547.76 too
  • can't test safari as I don't have it

mcjahudka avatar Sep 23 '13 17:09 mcjahudka

I am also having this exact same problem, in IE10, chrome, pretty much every browser. A named anchor will completely fail to work. Example:

<a href="/somepage.html#content">Go To Content</a>

will not fire the statechange event?

datadreamersllc avatar Oct 01 '13 18:10 datadreamersllc

:+1:

happens here as well. Currently debugging it. What I found out so far (using debug = true):

  1. calls pushState
  2. sets busy to true
  3. stores the state (i.e. setting the new location)
  4. triggers onpopstate
  5. logs History.onPopState: traditional anchor ["foobar"]
  6. Triggers anchorchange
  7. busy to false

... so the issue is: onPopState doesn't check if the current href is the same. It just checks if there's an anchor. And as far as I've seen, it can't really check if the current href is the same, because the location is already updated.

mweibel avatar Nov 15 '13 14:11 mweibel

I'm currently experimenting with the code to see what might fix it.. I have an experimental fix for now, would be cool if someone of you could test it as well:

                                // Reset the double check
                                History.doubleCheckComplete();

+                               var currentPath = document.location.pathname,
+                                       newPath = History.getShortUrl(History.getState().cleanUrl);
+
                                // Check for a Hash, and handle apporiatly
                                currentHash     = History.getHash();
-                               if ( currentHash ) {
+                               if ( currentHash && currentPath === newPath ) {
                                        // Expand Hash
                                        currentState = History.extractState(currentHash||document.location.href,true);
                                        if ( currentState ) {

This is around (Line 1695)[https://github.com/browserstate/history.js/blob/master/scripts/uncompressed/history.js#L1695]. The only problem I have currently is that the browser doesn't scroll to the anchor :/

mweibel avatar Nov 21 '13 10:11 mweibel

@mweibel thanks, that fix works for me. Unhelpfully, due to the way the site works, my fix for scrolling the page to the appropriate place is buried in our code.

eddhannay avatar Jan 07 '15 14:01 eddhannay

We had this in place for ~1 year and it worked pretty well (switched now to other systems). The scrolling I however never fixed. I guess you'd need to add specific data to it and add some custom logic.

mweibel avatar Jan 07 '15 14:01 mweibel

@mweibel Your fix worked for me. I handle scrolling with my own code te be able to use a animated scroll. Maybe you should pull request that fix.

ambroisemaupate avatar Mar 19 '15 10:03 ambroisemaupate

@mweibel Great fix thanks, it works for me. Why hasn't this been merged into the main history.js yet?

MartinDawson avatar May 07 '16 18:05 MartinDawson

Worked for me too, nearly three years later!

natebeaty avatar Jun 24 '16 03:06 natebeaty