如何判断页面是不是已跳转到 javascript 中的锚点 (#)?

Posted

技术标签:

【中文标题】如何判断页面是不是已跳转到 javascript 中的锚点 (#)?【英文标题】: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% 确定我的脚本总是会在滚动发生之前被触发,所以它只有在用户手动滚动页面时才会运行。无论如何,我不太喜欢这个解决方案,而是更喜欢事件驱动的东西。有什么建议吗?

编辑澄清:

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

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

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

【问题讨论】:

$(document).ready() 触发太早? 【参考方案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% 确定在每种情况下在每个浏览器上滚动之前都会触发文档就绪),但我可能会一瘸一拐地在一起。

以上是关于如何判断页面是不是已跳转到 javascript 中的锚点 (#)?的主要内容,如果未能解决你的问题,请参考以下文章

js如何判断一个页面是不是已跳转到指定的页面了呢

JS中如何判断用户离开了当前界面,跳转到了另一个界面?

js判断手机访问并跳转到相应页面

怎样判断手机端和电脑端自动跳转到各自的页面

Selenium2 点击按钮跳转页面,如何判断页面是不是加载完成(包含跳到对应页面有ajax的访问)

nodejs puppeteer打开一个页面后,在点击跳转到另一个页面 怎么判断这么页面是不是所有的元素都已加载完成