如何检测位置哈希的变化?
我使用 Ajax 和哈希进行导航。
有没有办法检查 window.location.hash
是否像这样改变?
http://example.com/blah#123 到 http://example.com/blah#456
如果我在文档加载时检查它,它就会起作用。
但是,如果我有基于 #hash 的导航,那么当我按下浏览器上的后退按钮时,它就不起作用(所以我从 blah#456 跳到 blah#123)。
它显示在地址框中,但我无法用 JavaScript 捕获它。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
真正做到这一点的唯一方法(以及“reallysimplehistory”如何做到这一点)是通过设置一个时间间隔来不断检查当前哈希值,并将其与之前的哈希值进行比较,我们这样做并让订阅者订阅更改后的哈希值。如果哈希值发生变化,我们会触发该事件。它并不完美,但浏览器本身并不支持此事件。
更新以使这个答案保持新鲜:
如果您使用 jQuery(今天对大多数人来说应该是有点基础的),那么一个很好的解决方案是使用 jQuery 为您提供的抽象,通过使用其事件系统来侦听 window 对象上的 hashchange 事件。
这里的好处是,您可以编写不需要担心 hashchange 支持的代码,但是您确实需要以不太为人所知的 jQuery 功能的形式施展一些魔法 jQuery 特殊事件。
使用此功能,当有人第一次尝试以任何方式(例如绑定到事件)使用该事件时,您基本上可以为任何事件运行一些设置代码。
在此设置代码中,您可以检查本机浏览器支持,如果浏览器本身没有实现此功能,您可以设置一个计时器来轮询更改,并触发 jQuery 事件。
这完全使您的代码不再需要理解这个支持问题,这种特殊事件的实现是微不足道的(获得一个简单的 98% 工作版本),但为什么要这样做 当其他人已经这样做时。
The only way to really do this (and is how the 'reallysimplehistory' does this), is by setting an interval that keeps checking the current hash, and comparing it against what it was before, we do this and let subscribers subscribe to a changed event that we fire if the hash changes.. its not perfect but browsers really don't support this event natively.
Update to keep this answer fresh:
If you are using jQuery (which today should be somewhat foundational for most) then a nice solution is to use the abstraction that jQuery gives you by using its events system to listen to hashchange events on the window object.
The nice thing here is you can write code that doesn't need to even worry about hashchange support, however you DO need to do some magic, in form of a somewhat lesser known jQuery feature jQuery special events.
With this feature you essentially get to run some setup code for any event, the first time somebody attempts to use the event in any way (such as binding to the event).
In this setup code you can check for native browser support and if the browser doesn't natively implement this, you can setup a single timer to poll for changes, and trigger the jQuery event.
This completely unbinds your code from needing to understand this support problem, the implementation of a special event of this kind is trivial (to get a simple 98% working version), but why do that when somebody else has already.
HTML5 指定
hashchange事件
。 此事件现在所有现代浏览器都支持。 以下浏览器版本添加了支持:
HTML5 specifies a
hashchange
event. This event is now supported by all modern browsers. Support was added in the following browser versions:请注意,对于 Internet Explorer 7 和 Internet Explorer 9,
if
语句将给出 true(对于 Windows 中的“onhashchange”),但window.onhashchange
永远不会触发,因此最好存储哈希并每 100 毫秒检查一次,对于所有版本的 Internet Explorer 是否已更改。编辑 -
从 jQuery 1.9 开始,不支持
$.browser.msie
。 来源:http://api.jquery.com/jquery.browser/Note that in case of Internet Explorer 7 and Internet Explorer 9 the
if
statment will give true (for "onhashchange" in windows), but thewindow.onhashchange
will never fire, so it's better to store hash and check it after every 100 millisecond whether it's changed or not for all versions of Internet Explorer.EDIT -
Since jQuery 1.9,
$.browser.msie
is not supported. Source: http://api.jquery.com/jquery.browser/我在 React 应用程序中使用它,使 URL 根据视图显示不同的参数用户已开启。
观看了哈希参数
我使用“ Then
It Works” 。 它适用于前进和后退浏览器按钮以及浏览器历史记录。
I was using this in a React application to make the URL display different parameters depending what view the user was on.
I watched the hash parameter using
Then
It works a treat. It works with forward and back browser buttons and also in the browser history.
在IE浏览器中处理History和window.location.hash有很多技巧:
正如原来的问题所说,如果你从页面a.html#b转到a.html#c,然后点击返回按钮,浏览器不知道页面已更改。 让我用一个例子来说明:window.location.href 将是“a.html#c”,无论您是在 a.html#b 还是 a.html#c。
实际上,只有元素 '' 时,a.html#b 和 a.html#c 才会存储在历史记录中 和 '' 中
但是,如果您将 iframe 放入页面中,从该 iframe 中的 a.html#b 导航到 a.html#c,然后单击后退按钮,iframe.contentWindow.document.location.href 将按预期更改。
如果您在代码中使用“document.domain=something”,那么您将无法访问 iframe.contentWindow.document.open()”(许多历史记录管理器都会这样做)< /p>
)知道这不是真正的回复,但也许 IE 历史记录对某人有用。
There are a lot of tricks to deal with History and window.location.hash in IE browsers:
As original question said, if you go from page a.html#b to a.html#c, and then hit the back button, the browser doesn't know that page has changed. Let me say it with an example: window.location.href will be 'a.html#c', no matter if you are in a.html#b or a.html#c.
Actually, a.html#b and a.html#c are stored in history only if elements '<a name="#b">' and '<a name="#c">' exists previously in the page.
However, if you put an iframe inside a page, navigate from a.html#b to a.html#c in that iframe and then hit the back button, iframe.contentWindow.document.location.href changes as expected.
If you use 'document.domain=something' in your code, then you can't access to iframe.contentWindow.document.open()' (and many History Managers does that)
I know this isn't a real response, but maybe IE-History notes are useful to somebody.
Firefox 从 3.6 开始就有 onhashchange 事件。 请参阅window.onhashchange。
Firefox has had an onhashchange event since 3.6. See window.onhashchange.
您可以轻松地在“window.location”对象的“hash”属性上实现观察者(“watch”方法)。
Firefox 有其自己的用于监视对象更改的实现,但是如果您使用其他实现(例如监视对象属性的更改JavaScript) - 对于其他浏览器,这可以解决问题。
代码将如下所示:
然后您可以测试它:
当然,这将触发您的观察者函数。
You could easily implement an observer (the "watch" method) on the "hash" property of "window.location" object.
Firefox has its own implementation for watching changes of object, but if you use some other implementation (such as Watch for object properties changes in JavaScript) - for other browsers, that will do the trick.
The code will look like this:
Then you can test it:
And of course that will trigger your observer function.
另一个很棒的实现是 jQuery History ,如果支持的话,它将使用本机 onhashchange 事件浏览器,如果没有,它将为浏览器使用适当的 iframe 或间隔,以确保成功模拟所有预期的功能。 它还提供了一个很好的接口来绑定到某些状态。
另一个值得注意的项目是 jQuery Ajaxy 它几乎是 jQuery History 的扩展将 ajax 添加到其中。 当你开始使用带有哈希值的ajax时,它会变得相当复杂!
Another great implementation is jQuery History which will use the native onhashchange event if it is supported by the browser, if not it will use an iframe or interval appropriately for the browser to ensure all the expected functionality is successfully emulated. It also provides a nice interface to bind to certain states.
Another project worth noting as well is jQuery Ajaxy which is pretty much an extension for jQuery History to add ajax to the mix. As when you start using ajax with hashes it get's quite complicated!
就是这样......现在,只要您点击后退或前进按钮,页面就会根据新的哈希值重新加载。
That's it... now, anytime you hit your back or forward buttons, the page will reload as per the new hash value.
我一直在使用 path.js 进行客户端路由。 我发现它非常简洁和轻量(它也已发布到 NPM),并且使用基于哈希的导航。
path.js NPM
path.js GitHub
I've been using path.js for my client side routing. I've found it to be quite succinct and lightweight (it's also been published to NPM too), and makes use of hash based navigation.
path.js NPM
path.js GitHub
一个简短的示例:
单击按钮更改哈希值:
A short and simple example:
Click on buttons to change the hash: