Pat*_*rik 6 javascript ajax jquery hashchange
我有这个问题(我使用的是jQuery,但我并不局限于此):
我正在使用Anchor导航(#id)和Ajax请求的组合.为了使页面移动到位(使用锚导航)或获取信息(使用Ajax),我使用onhashchange事件.
编辑:我有一个小错字.我忘了检查mouseDown标志是否为true并且是否触发了hashchange事件,所以我添加了if语句.
使用jQuery它看起来像这样:(当然这个代码包含在一个函数中并在DOM加载时初始化但是对于这个问题并不重要)
$(window).bind('hashchange', function(e) { }
Run Code Online (Sandbox Code Playgroud)
为了确保只有支持onhashchange的浏览器读取代码,我将其封装为:
if ('onhashchange' in window) {
$(window).bind('hashchange', function(e) { }
}
Run Code Online (Sandbox Code Playgroud)
我的网络应用程序是这样制作的,我只想在浏览器中点击后退/前进按钮时触发onhashchange事件.要做到这一点,我喜欢这样:
if ('onhashchange' in window) {
$(window).bind('mousedown hashchange', function(e) { }
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我在视口中单击,我将触发mousedown事件.如果mousedown事件被触发,我知道我没有单击浏览器后退/前进按钮,我可以使用这样的标志停止onhashchange事件:
var mouseDown = false;
if ('onhashchange' in window) {
$(window).bind('mousedown hashchange', function(e) {
if (e.type === 'mousedown') {
mouseDown = true;
}
if (mouseDown && e.type === 'hashchange') {
// if the mousedown event was triggered and when the haschange event triggers,
// we need to stop the hashchange event and restore the mouseDown flag
mouseDown = false;
e.stopPropagation();
}
if (!mouseDown && e.type === 'hashchange') {
// Do the onhashchange stuff here
}
}
}
Run Code Online (Sandbox Code Playgroud)
这会导致IE出现问题,因为它无法将鼠标事件绑定到窗口对象(?).IE永远不会"看到"mousedown事件.
要解决这个IE问题,我可以使用"clientY"属性.此属性在IE中的所有事件调用中传递,并告诉您鼠标的坐标.如果e.clientY小于0,则鼠标位于视口之外,我将通过单击浏览器后退/前进按钮来了解我触发了onhashchange.它现在看起来像这样:
var mouseDown = false;
if ('onhashchange' in window) {
$(window).bind('mousedown hashchange', function(e) {
// IE: Use e.clientY to check if the mouse position was within the viewport (i.e. not a nagative value for Y)
// !IE: Use e.type
if (e.type === 'mousedown' || e.clientY > 0 ) {
mouseDown = true;
}
if (mouseDown && e.type === 'hashchange') {
// if the mousedown event was triggered and when the haschange event triggers,
// we need to stop the hashchange event and restore the mouseDown flag
mouseDown = false;
e.stopPropagation();
}
if (!mouseDown && e.type === 'hashchange') {
// Do the onhashchange stuff here
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个解决方案就像一个魅力,直到我不得不添加支持键盘上的箭头导航.现在,鼠标在屏幕上的位置并不重要.只要IE窗口处于"活动"状态,就会在敲击键盘时触发键控输入的keydown事件.这意味着clientY检查不再按预期工作.
问题:
据我所知,onhashchange必须绑定到window对象.如果我希望能够通过侦听另一个事件来控制一个事件,则必须在同一个回调函数中处理所有事件.
我怎样才能让它发挥作用?
所以,简单来说——
“如何区分后退/前进按钮按下与来自与 DOM 交互的导航”。
您可能需要一个标志,这样当您从代码更改 URL 的哈希部分时,您可以设置此标志,忽略 hashchange 事件,然后取消设置该标志。在这种情况下,该事件将被忽略(一种与您尝试执行的操作相反的解决方案)。您显然希望将其包装在一个函数中。
然而,一般来说,使用 hashchange 事件进行导航的应用程序通常会使用 hashchange 事件作为更改应用程序状态的方法。因此,只有一个入口点,您无需区分事件是由浏览器导航生成还是由 dom 交互生成。我可能会建议改变你的方法。
我还想向您指出这样一个事实:所有浏览器都可以支持历史记录(甚至使用 iFrame hack 的 IE6 和 IE7)。看一下jQuery 历史记录插件