【发布时间】:2011-06-02 23:23:42
【问题描述】:
我遇到了这个问题(我正在使用 jQuery,但我不限于此):
我正在使用锚导航 (#id) 和 Ajax 请求的组合。为了让页面移动到位(使用锚导航)或获取信息(使用 Ajax),我使用了 onhashchange 事件。
编辑:我有一点错字。我忘了检查 mouseDown 标志是否为真并且 hashchange 事件被触发,所以我添加了 if 语句。
使用 jQuery,它看起来像这样:(当然,这段代码被包装在一个函数中,并在 DOM 加载时初始化,但对于这个问题并不重要)
$(window).bind('hashchange', function(e) { }
为了确保只有支持 onhashchange 的浏览器能够读取我这样封装的代码:
if ('onhashchange' in window) {
$(window).bind('hashchange', function(e) { }
}
我的网络应用程序是这样制作的,我只希望在我点击浏览器中的后退/前进按钮时触发 onhashchange 事件。为此,我这样做:
if ('onhashchange' in window) {
$(window).bind('mousedown hashchange', function(e) { }
}
现在,如果我在视口内单击,我将触发 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
}
}
}
这会导致 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
}
}
}
这个解决方案非常有效,直到我不得不添加对使用键盘上的箭头进行导航的支持。现在,鼠标在屏幕上的位置无关紧要。只要 IE 窗口处于“活动状态”,在敲击键盘时就会触发监听键盘输入的 keydown 事件。这意味着 clientY 检查不再按预期工作。
问题:
据我所知,onhashchange 必须绑定到 window 对象。如果我希望能够通过侦听另一个事件来控制一个事件,则必须在同一个回调函数中处理所有事件。
我怎样才能让它工作?
【问题讨论】:
-
('onhashchange' in window) 如果尚未定义,则始终返回 false,如果已定义,则始终返回 true。这并不意味着浏览器实际上会在 hashchange 上执行代码 这类似于 window.onload ,除非实际分配了一个函数,否则它是未定义的,即使实际上所有浏览器都支持它。
-
是的,我故意省略了函数声明,因为我认为它与问题无关。 DOM 加载时调用绑定 hashchange 事件的函数。
标签: javascript jquery ajax hashchange