监控 location.hash 是 XHR 应用程序中历史记录的解决方案吗?
众所周知,在 XHR(又名 AJAX)Web 应用程序中,不会构建应用程序的历史记录,并且单击刷新按钮通常会将用户移出他/她当前的活动。 我偶然发现 location.hash (例如 http://anywhere/index.html#somehashvalue
)来规避刷新问题(使用 location.hash 通知您的应用程序其当前状态并使用页面加载处理程序重置该状态)。 这真的很好而且很简单。
这让我考虑使用 location.hash 来跟踪我的应用程序的历史记录。 我不想使用现有的库,因为它们使用 iframe 等。所以这是我的一点一毛钱:当应用程序页面加载时,我启动这个:(
setInterval(
function(){
if (location.hash !== appCache.currentHash) {
appCache.currentHash = location.hash;
appCache.history.push(location.hash);
/* ... [load state using the hash value] ... */
return true;
}
return false;
}, 250
);
appCache 是包含应用程序变量的预定义对象)想法是从哈希值触发应用程序中的每个操作。 在不错的浏览器中,哈希值更改会向历史记录添加一个条目,而在 IE (<= 7) 中则不会。 在所有浏览器中,向后或向前导航到具有另一个哈希值的页面不会触发页面刷新。 这就是间隔函数发挥作用的地方。 通过该函数,每次检测到哈希值更改(以编程方式或通过单击后退或前进),应用程序都可以采取适当的操作。 该应用程序可以跟踪它自己的历史记录,并且我应该能够在应用程序中显示历史记录按钮(特别是对于 IE 用户)。
据我所知,这可以跨浏览器工作,并且在内存或处理器资源方面没有成本。 所以我的问题是:这是否是管理 XHR 应用程序历史记录的可行解决方案? 优缺点都有什么?
更新:因为我使用自制框架,所以我不想使用现有框架之一。 为了能够在 IE 中使用 location.hash 并将其记录在历史记录中,我创建了一个简单的脚本(是的,它需要一个 iframe),这可能对您有用。 我在我的网站上发布了它,请随意使用/修改/批评它。
As is well known, in XHR (aka AJAX) web applications no history for your app is build and clicking the refresh button often moves the user out of his/her current activity. I stumbled upon location.hash (e.g. http://anywhere/index.html#somehashvalue
) to circumvent the refresh problem (use location.hash to inform your app of it's current state and use a page load handler to reset that state). It's really nice and simple.
This brought me to thinking about using location.hash to track the history of my app. I don't want to use existing libraries, because they use iframes etc. So here's my nickel and dime: when the application page loads I start this:
setInterval(
function(){
if (location.hash !== appCache.currentHash) {
appCache.currentHash = location.hash;
appCache.history.push(location.hash);
/* ... [load state using the hash value] ... */
return true;
}
return false;
}, 250
);
(appCache is a predefined object containing application variables) The idea is to trigger every action in the application from the hash value. In decent browsers a hash value change adds an entry to the history, in IE (<= 7) it doesn't. In all browsers, navigating back or forward to a page with another hash value doesn't trigger a page refresh. That's where the intervalled function takes over. With the function everytime the hash value change is detected (programmatically, or by clicking back or forward) the app can take appropriate action. The application can keep track of it's own history and I should be able to present history buttons in the application (especially for IE users).
As far as I can tell this works cross browser and there's no cost in terms of memory or processor resources. So my question is: would this be a viable solution to manage the history in XHR-apps? What are the pros and cons?
Update: because I use my homebrew framework, I didn't want to use one of the existing frameworks. To be able to use location.hash in IE and having it in it's history too, I created a simple script (yes, it's needs an iframe) which may be of use to you. I published it on my site, feel free to use/modify/critizise it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
大多数解决方案往往会混淆 3 个问题:
基于
window.location.hash
的解决方案可以在大多数情况下解决所有三个问题:hash 中的值
映射到应用程序/网页的状态,因此用户可以按“后退”/“前进”/“刷新”之一并跳转到哈希中现在的状态。 他们还可以添加书签,因为地址栏中的值已更改。 (请注意,与不影响浏览器历史记录的哈希相关的 IE 需要隐藏的iframe
)。不过,我只是想指出,仅使用 iframe 解决方案也可以在不监视
window.location.hash
的情况下使用,这也是一个非常有效的解决方案。谷歌地图就是一个很好的例子。 为每个用户操作捕获的状态太大,无法放入 window.location.hash(地图质心、搜索结果、卫星与地图视图、信息窗口等)。 因此,他们将状态保存到嵌入隐藏
iframe
中的表单中。 顺便说一句,这也解决了[软]“刷新”问题。 他们通过“链接到此页面”按钮单独解决可书签性问题。我只是认为值得了解/分离您正在考虑的问题领域。
There are 3 issues that tend to get munged together by most solutions:
The
window.location.hash
based solutions can solve all three for most cases: the value in thehash
maps to a state of the application/webpage, so a user can press one of "back"/"forward"/"refresh" and jump to the state now in the hash. They can also bookmark because the value in the address bar has changed. (Note that a hiddeniframe
is needed for IE related to the hash not affecting the browser's history).I just wanted to note however that an iframe only solution can be used without monitoring
window.location.hash
for a very effective solution too.Google maps is a great example of this. The state captured for each user action is way too large to be placed into window.location.hash (map centroid, search results, satellite vs map view, info windows, etc). So they save state into a form embedded in a hidden
iframe
. Incidentally this solves the [soft] "refresh" issue too. They solve bookmarkability separately via a "Link to this page" button.I just thought it's worthing knowing/separating the problem domains you are thinking about.
我认为你会很难知道用户是前进还是后退。
假设 url 以 /myapp#page1 开头,那么您就开始跟踪状态。
然后用户执行一些操作来使 url /myapp#page2
然后用户执行某些操作以再次生成 url /myapp#page1。 现在他们的历史是模糊的,你不知道要删除什么或不删除什么。
历史框架使用 iframe 来解决您提到的浏览器不一致问题。 您只需在需要 iframe 的浏览器中使用它们即可。
另一个缺点是,用户总是会先选择浏览器的后退按钮,然后再选择您的自定义后退按钮。 我感觉每 250 毫秒读取历史记录的延迟也会很明显。 也许你可以把间隔做得更紧,但我不知道这是否会让事情表现得很糟糕。
我使用过 yui 的历史记录管理器,虽然它并不是在所有浏览器(尤其是 ie6)中始终完美工作,但它已经被很多用户和开发人员使用。 他们使用的模式也非常灵活。
I think you'll have a tricky time knowing if a user went forward or back.
Say the url starts /myapp#page1 so you start tracking states.
Then the user does something to make the url /myapp#page2
Then the user does something to make the url /myapp#page1 again. Now their history is ambiguous and you won't know what to remove or not.
The history frameworks use iframes to get around the browser inconsistencies you mentioned. You only need to use iframes in the browsers that need them.
Another con is that users will always go for their browsers back button before they will go for your custom back button. I have a feeling the delay on reading the history every 250ms will be noticeable too. Maybe you can do the interval even tighter, but then I don't know if that'll make things perform badly.
I've used yui's history manager, and although it doesn't work perfectly all the time in all browsers (especially ie6), it's been used by a lot of users and developers. The pattern they use is pretty flexible too.
所有这些东西对于支持全系列浏览器都很重要,但希望它的需求将会消失。 IE8 和 FF3.6 都引入了对 onhashchange 的支持。 我想其他人也会效仿。 在使用超时或 iframe 之前检查此功能的可用性是一个好主意,因为它确实是目前最好的解决方案 - 而且它甚至可以在 IE 中工作!
All that stuff is important for supporting the full range of browsers, but hopefully the need for it will go away. IE8 and FF3.6 both introduced support for onhashchange. I imagine that others will follow suit. It would be a good idea to check for the availability of this functionality before using timeouts or iframes, as it is really the nicest solution currently out there - and it even works in IE!