【问题标题】:How can I tell if a page has jumped to the anchor (#) in javascript?如何判断页面是否已跳转到 javascript 中的锚点 (#)?
【发布时间】:2011-04-03 10:14:21
【问题描述】:

我有一些 javascript 可以出现在许多不同的页面上。有时,这些页面是通过包含锚引用的 URL 访问的(例如#comment-100)。在这些情况下,我希望 javascript 延迟执行,直到窗口跳转之后。现在我只是在使用延迟,但这很不合时宜,显然并非在所有情况下都有效。我似乎找不到任何与窗口“跳转”相对应的 DOM 事件。

除了简单的延迟之外,我想出的唯一解决方案是让 JS 在 URL 中查找锚点,如果找到,请注意 scrollTop 的变化。但这似乎有问题,而且我不能 100% 确定我的脚本总是会在滚动发生之前被触发,所以它只有在用户手动滚动页面时才会运行。无论如何,我不太喜欢这个解决方案,而是更喜欢事件驱动的东西。有什么建议吗?

编辑澄清:

我不想检测哈希更改。举个例子:

  1. 页面 index.php 包含指向 post.php#comment-1 的链接
  2. 用户点击post.php#comment-1的链接
  3. post.php#comment-1 加载
  4. $(document).ready 触发
  5. 不久之后,浏览器向下滚动到#comment-1

我正在尝试可靠地检测第 5 步何时发生。

【问题讨论】:

  • $(document).ready() 触发太早?

标签: javascript jquery dom javascript-events


【解决方案1】:

要检测元素何时出现在屏幕上,请使用appear 插件:

$('#comment-1').appear(function() {
  $(this).text('scrolled');
});

【讨论】:

    【解决方案2】:

    您可以在现代浏览器中查看 window.onhashchange。如果你想要交叉兼容,请查看http://benalman.com/projects/jquery-hashchange-plugin/

    此页面还有关于 window.onhashchange 的更多信息。

    编辑:您基本上用类似的链接约定替换所有锚名称,然后使用 .scrollTo 来处理滚动:

    $(document).ready(function () {
      // replace # with #_ in all links containing #
      $('a[href*=#]').each(function () {
          $(this).attr('href', $(this).attr('href').replace('#', '#_'));
      });
    
      // scrollTo if #_ found
      hashname = window.location.hash.replace('#_', '');
      // find element to scroll to (<a name=""> or anything with particular id)
      elem = $('a[name="' + hashname + '"],#' + hashname);
    
      if(elem) {
           $(document).scrollTo(elem, 800,{onAfter:function(){
            //put after scroll code here }});
      }
    });
    

    请参阅jQuery: Scroll to anchor when calling URL, replace browsers behaviour 了解更多信息。

    【讨论】:

    • @bryan - 问题是没有检测到哈希更改,问题是检查是否在使用哈希的情况下,窗口已经滚动到正确的位置。
    • @Peter Ajtai, Aaron:可能想要使用 .scrollTo jQ 插件来处理您的滚动。您可以使用 onAfter 参数来运行您的函数调用。 flesler.blogspot.com/2007/10/jqueryscrollto.html
    • 我得看看 .scrollTo 是否可以处理初始页面加载在 URL 中有锚点的情况。我的印象是 .scrollTo 仅在单击当前页面中的锚点链接时处理滚动。
    • 不幸的是 .scrollTo 似乎无法处理这种情况,尽管我很想被证明是错误的!
    • @Aaron:实际上,$.scrollTo 可以处理跨页链接。我在答案中编辑了一些代码,以向您展示我在说什么。
    【解决方案3】:

    看来您可以使用window.onscroll。我刚才测试了这段代码:

    <a name="end" />
    <script type="text/javascript">
        window.onscroll = function (e) {
            alert("scrolled");
    }
    </script>
    

    这似乎有效。

    编辑:嗯,它在 IE8 中不起作用。不过它适用于 Firefox 和 Chrome。

    编辑:jQuery 有一个 .scroll() 处理程序,但它会在 IE 上滚动之前触发,并且似乎不适用于 Chrome 或 Firefox。

    【讨论】:

    • @Gilsham - 如果窗口因其他原因滚动怎么办?
    • true,我猜你必须在运行一次代码后取消绑定它,只需添加行 window.onscroll = null;在警报之后,它接缝很好
    • 你也可以在页面加载后检查window.pageYOffset,如果它大于0,页面已经向下滚动
    • 问题是知道何时检查pageYOffset。文档就绪触发太早了。
    • jquery 的 .scroll() 处理程序可能是我见过的最可行的解决方案。我得做一些测试。我担心竞争条件(我不能 100% 确定在每种情况下在每个浏览器上滚动之前都会触发文档就绪),但我可能会一瘸一拐地在一起。
    猜你喜欢
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    相关资源
    最近更新 更多