javascript - 仅使用浏览器按钮的 Onhashchange

标签 javascript jquery ajax hashchange

我遇到了这个问题(我正在使用 jQuery 但我不限于此):

我正在使用 anchor 导航 (#id) 和 Ajax 请求的组合。为了让页面移动到位(使用 anchor 导航)或获取信息(使用 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) { }
}

现在,如果我在视口(viewport)内单击,我将触发 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 出现问题,因为它表明您无法将鼠标事件绑定(bind)到窗口对象 (?)。 IE 永远不会“看到”mousedown 事件。

要解决这个 IE 问题 我可以使用“clientY”属性。此属性在 IE 中的所有事件调用中传递,并告诉您鼠标的坐标。如果 e.clientY 小于 0,则鼠标在视口(viewport)之外,我将知道我通过单击浏览器后退/前进按钮触发了 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 必须绑定(bind)到 window 对象。如果我希望能够通过监听另一个事件来控制一个事件,则必须在同一个回调函数中处理所有事件。

我怎样才能让它工作?

最佳答案

所以,简单地说-

“我如何区分按下后退/前进按钮与来自与 DOM 交互的导航”。

您可能希望有一个标志,这样当您从代码更改 URL 的散列部分时,您可以设置此标志,忽略 hashchange 事件,然后取消设置标志。在这种情况下,该事件将被忽略(一种关于您要执行的操作的反向解决方案)。您显然希望将其包装在一个函数中。

但一般来说,使用 hashchange 事件进行导航的应用程序通常会使用 hashchange 事件作为更改应用程序状态的手段。因此入口只有一个,不需要区分事件是浏览器导航还是dom交互产生的。我可能会建议您改变方法。

我还要指出一个事实,即所有浏览器都支持历史记录(甚至使用 iFrame hack 的 IE6 和 IE7)。看看 jQuery history plugin

关于javascript - 仅使用浏览器按钮的 Onhashchange,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4586787/

相关文章:

javascript - 我们什么时候应该使用 Backbone JS 集合?

javascript - 处理 Node 的异步特性 - writeFile 回调

javascript - 获取第二个文本区域之后的所有输入

jquery - 向远程验证属性 MVC3 添加延迟

jquery - 使用 JQuery Ajax 处理 MVC5 错误

javascript - 使用 Ajax.BeginForm 更新表单

javascript - 没有为 res Node 定义错误函数

javascript - 使用 PUG (npm/gulp) 生成本地 HTML 文件

javascript - 使用 JQuery 创建同一页面事件

php - 是否有一种标准的方法来处理与 PHP 中的条件分开的设计 (CSS)?