Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hashchange event not working in 2.8 #1807

Closed
Leopoldthecoder opened this issue Oct 13, 2017 · 9 comments
Closed

hashchange event not working in 2.8 #1807

Leopoldthecoder opened this issue Oct 13, 2017 · 9 comments

Comments

@Leopoldthecoder
Copy link

Version

2.8.0 & 3.0.0

Reproduction link

http://jsfiddle.net/9r6xhqbp/41/

Steps to reproduce

Switch between /home and /foo

What is expected?

hashchange triggers and you'll see 1s printed in the console.

What is actually happening?

Nothing is printed.


hashchange works fine in 2.7.0: http://jsfiddle.net/9r6xhqbp/40/

@yyx990803
Copy link
Member

In 2.8 & 3.0 hash mode will use pushState when it's available, which doesn't seem to trigger hashchange event anymore. This is unfortunately an unintended breaking behavior, although technically is not part of the API contract.

I'd recommend using a more implementation-agnostic way to detect route change, e.g. router.afterEach.

@huige555551
Copy link

it can also be work like this instead of window.addEventListener('hashchange')
watch: {
'$route': function(){}
}

@julianxhokaxhiu
Copy link

julianxhokaxhiu commented Jan 23, 2018

@yyx990803 Sorry I don't get why the default behavior overrides a well known configuration. If I use mode: 'hash' I expect an hash change, not a push state.

What about introducing a dedicated mode like mode: 'pushstate'? And maybe make it as a default one.

//EDIT: checking it again it seems there is already the history mode. See https://router.vuejs.org/en/api/options.html#mode

Does that mean you fixed it?

@yyx990803
Copy link
Member

@julianxhokaxhiu hash mode only guarantees the URLs are expressed using the hash, but the hash may be changed by either pushState or direct hash mutation. The former does not emit the hashchange event.

The API has never made any guarantee on whether a hashchange event will be dispatched in hash mode. As suggested, you should use the router's own API to detect route change.

@julianxhokaxhiu
Copy link

My target was not related to the Vue ecosystem, but other libraries that may interact with native DOM events.

I get that the library was not giving guarantee, but in my honest opinion I think that when you keep such a feature for long time, you definitely do not want to change it under the hood.
Instead you enable everything with a flag detecting if the user wants that feature too, because instead it is a feature ( aside the fact it is auto-detected anyway as a browser feature ), not a bugfix.

@yyx990803
Copy link
Member

@julianxhokaxhiu for your use case, a very simple workaround: dispatch a hashchange event yourself in router.afterEach.

@julianxhokaxhiu
Copy link

Sure, the workaround may work and it's fine. What happens if you have already that event dispatched? This means that you have to check if the push-state is supported first right? So again, this means overhead on top of a well known behavior.

Unless Vue Router gives a guarantee that the afterEach is called only when a push-state happens.

@zhangwentao
Copy link

function pushHash (path) {
  if (supportsPushState) {
    pushState(getUrl(path));
  } else {
    window.location.hash = path;
  }
}

all because above

@duenyang
Copy link

It also doesn't work in version 2.1.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants