如何检测位置哈希的变化?

发布于 2024-07-15 13:10:57 字数 450 浏览 16 评论 0 原文

我使用 Ajax 和哈希进行导航。

有没有办法检查 window.location.hash 是否像这样改变?

http://example.com/blah#123http://example.com/blah#456

如果我在文档加载时检查它,它就会起作用。

但是,如果我有基于 #hash 的导航,那么当我按下浏览器上的后退按钮时,它就不起作用(所以我从 blah#456 跳到 blah#123)。

它显示在地址框中,但我无法用 JavaScript 捕获它。

I am using Ajax and hash for navigation.

Is there a way to check if the window.location.hash changed like this?

http://example.com/blah#123 to http://example.com/blah#456

It works if I check it when the document loads.

But if I have #hash based navigation it doesn't work when I press the back button on the browser (so I jump from blah#456 to blah#123).

It shows inside the address box, but I can't catch it with JavaScript.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

天涯离梦残月幽梦 2024-07-22 13:10:57

真正做到这一点的唯一方法(以及“reallysimplehistory”如何做到这一点)是通过设置一个时间间隔来不断检查当前哈希值,并将其与之前的哈希值进行比较,我们这样做并让订阅者订阅更改后的哈希值。如果哈希值发生变化,我们会触发该事件。它并不完美,但浏览器本身并不支持此事件。


更新以使这个答案保持新鲜:

如果您使用 jQuery(今天对大多数人来说应该是有点基础的),那么一个很好的解决方案是使用 jQuery 为您提供的抽象,通过使用其事件系统来侦听 window 对象上的 hashchange 事件。

$(window).on('hashchange', function() {
  //.. work ..
});

这里的好处是,您可以编写不需要担心 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.

$(window).on('hashchange', function() {
  //.. work ..
});

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.

假装不在乎 2024-07-22 13:10:57

HTML5 指定 hashchange事件。 此事件现在所有现代浏览器都支持。 以下浏览器版本添加了支持:

  • Internet Explorer 8
  • Firefox 3.6
  • Chrome 5
  • Safari 5
  • Opera 10.6

HTML5 specifies a hashchange event. This event is now supported by all modern browsers. Support was added in the following browser versions:

  • Internet Explorer 8
  • Firefox 3.6
  • Chrome 5
  • Safari 5
  • Opera 10.6
﹉夏雨初晴づ 2024-07-22 13:10:57

请注意,对于 Internet Explorer 7 和 Internet Explorer 9,if 语句将给出 true(对于 Windows 中的“onhashchange”),但 window.onhashchange永远不会触发,因此最好存储哈希并每 100 毫秒检查一次,对于所有版本的 Internet Explorer 是否已更改。

    if (("onhashchange" in window) && !($.browser.msie)) {
         window.onhashchange = function () {
              alert(window.location.hash);
         }
         // Or $(window).bind( 'hashchange',function(e) {
         //       alert(window.location.hash);
         //   });
    }
    else {
        var prevHash = window.location.hash;
        window.setInterval(function () {
           if (window.location.hash != prevHash) {
              prevHash = window.location.hash;
              alert(window.location.hash);
           }
        }, 100);
    }

编辑 -
从 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 the window.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.

    if (("onhashchange" in window) && !($.browser.msie)) {
         window.onhashchange = function () {
              alert(window.location.hash);
         }
         // Or $(window).bind( 'hashchange',function(e) {
         //       alert(window.location.hash);
         //   });
    }
    else {
        var prevHash = window.location.hash;
        window.setInterval(function () {
           if (window.location.hash != prevHash) {
              prevHash = window.location.hash;
              alert(window.location.hash);
           }
        }, 100);
    }

EDIT -
Since jQuery 1.9, $.browser.msie is not supported. Source: http://api.jquery.com/jquery.browser/

栖竹 2024-07-22 13:10:57

我在 React 应用程序中使用它,使 URL 根据视图显示不同的参数用户已开启。

观看了哈希参数

window.addEventListener('hashchange', doSomethingWithChangeFunction);

我使用“ Then

function doSomethingWithChangeFunction () {
    let urlParam = window.location.hash; // Get new hash value

    // ... Do something with new hash value
};

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

window.addEventListener('hashchange', doSomethingWithChangeFunction);

Then

function doSomethingWithChangeFunction () {
    let urlParam = window.location.hash; // Get new hash value

    // ... Do something with new hash value
};

It works a treat. It works with forward and back browser buttons and also in the browser history.

要走干脆点 2024-07-22 13:10:57

在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.

噩梦成真你也成魔 2024-07-22 13:10:57

Firefox 从 3.6 开始就有 onhashchange 事件。 请参阅window.onhashchange

Firefox has had an onhashchange event since 3.6. See window.onhashchange.

烟酒忠诚 2024-07-22 13:10:57

您可以轻松地在“window.location”对象的“hash”属性上实现观察者(“watch”方法)。

Firefox 有其自己的用于监视对象更改的实现,但是如果您使用其他实现(例如监视对象属性的更改JavaScript) - 对于其他浏览器,这可以解决问题。

代码将如下所示:

window.location.watch(
    'hash',
    function(id,oldVal,newVal){
        console.log("the window's hash value has changed from "+oldval+" to "+newVal);
    }
);

然后您可以测试它:

var myHashLink = "home";
window.location = window.location + "#" + myHashLink;

当然,这将触发您的观察者函数。

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:

window.location.watch(
    'hash',
    function(id,oldVal,newVal){
        console.log("the window's hash value has changed from "+oldval+" to "+newVal);
    }
);

Then you can test it:

var myHashLink = "home";
window.location = window.location + "#" + myHashLink;

And of course that will trigger your observer function.

酒废 2024-07-22 13:10:57

另一个很棒的实现是 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!

烟柳画桥 2024-07-22 13:10:57
var page_url = 'http://www.yoursite.com/'; // full path leading up to hash;
var current_url_w_hash = page_url + window.location.hash; // now you might have something like: http://www.yoursite.com/#123

function TrackHash() {
    if (document.location != page_url + current_url_w_hash) {
        window.location = document.location;
    }
    return false;
}
var RunTabs = setInterval(TrackHash, 200);

就是这样......现在,只要您点击后退或前进按钮,页面就会根据新的哈希值重新加载。

var page_url = 'http://www.yoursite.com/'; // full path leading up to hash;
var current_url_w_hash = page_url + window.location.hash; // now you might have something like: http://www.yoursite.com/#123

function TrackHash() {
    if (document.location != page_url + current_url_w_hash) {
        window.location = document.location;
    }
    return false;
}
var RunTabs = setInterval(TrackHash, 200);

That's it... now, anytime you hit your back or forward buttons, the page will reload as per the new hash value.

私野 2024-07-22 13:10:57

我一直在使用 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

(り薆情海 2024-07-22 13:10:57

一个简短的示例

单击按钮更改哈希值:

window.onhashchange = () => console.log(`Hash changed -> ${window.location.hash}`)
<button onclick="window.location.hash=Math.random()">hash to Math.Random</button>

<button onclick="window.location.hash='ABC'">Hash to ABC</button>

<button onclick="window.location.hash='XYZ'">Hash to XYZ</button>

A short and simple example:

Click on buttons to change the hash:

window.onhashchange = () => console.log(`Hash changed -> ${window.location.hash}`)
<button onclick="window.location.hash=Math.random()">hash to Math.Random</button>

<button onclick="window.location.hash='ABC'">Hash to ABC</button>

<button onclick="window.location.hash='XYZ'">Hash to XYZ</button>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文