【问题标题】:Vue Router how to scroll to same hash consecutivelyVue路由器如何连续滚动到相同的哈希
【发布时间】:2020-12-11 05:39:09
【问题描述】:

我目前正在开发一个基于 Vue 并使用 Vue Router 进行路由的站点。我处理锚链接的滚动行为的方法如下:

const router = new VueRouter({
    routes,
    scrollBehavior (to) {
        if (to.hash) {
            return { 
                selector: to.hash,
                offset: { x: 0, y: 140 }
            }
        }
        return { x: 0, y: 0 }
    }
})

我的链接是按以下方式构建的:

<router-link class="insurance-link d-block" to="#hogar">
    <img class="insurance-logo img-fluid" src="@/assets/home-icon.svg">
    Hogar
</router-link>

如果我第一次单击链接,它会滚动到锚点位置,但如果我滚动回顶部并第二次单击它,它将不会再次滚动回该位置。如果我单击另一个锚链接,然后单击上一个链接,一切正常。对可能发生的事情有任何想法吗?

【问题讨论】:

标签: javascript vue.js vue-component vue-router


【解决方案1】:

我相信这种行为是由于 Vue 阻止了点击事件的传播,当你已经在点击的哈希处时,路由器认为它没有变化,所以忽略它。 Vue 文档状态:

在 HTML5 历史模式下,router-link 会拦截点击事件,所以 浏览器不会尝试重新加载页面。

使用router-link default slot 是获得更多控制权的一种方式。这似乎提供了一种解决方法:

<router-link to="#hogar" v-slot="{ href }">
    <a :href="href">Hogar</a>
</router-link>

【讨论】:

  • 嘿诺亚!感谢您的回答。我已将所有链接移至明确声明路径名和哈希值,但遗憾的是这并没有奏效。
  • 啊,我错了。我更新了答案,希望有更好的解决方案。
【解决方案2】:

最简单的解决方法是改用&lt;a&gt;

<a class="insurance-link d-block" href="#hogar">
    <img class="insurance-logo img-fluid" src="@/assets/home-icon.svg">
    Hogar
</a>

如果您想使用&lt;router-link&gt; 并使其在您第二次单击路由器链接时工作,您需要添加自定义 onclick 处理程序,如下所示:

<router-link class="insurance-link d-block" to="#hogar" @click.native="scrollToId('hogar')">
    <img class="insurance-logo img-fluid" src="@/assets/home-icon.svg">
    Hogar
</router-link>

并添加到您的 vue 方法中:

methods: {
  scrollToId(id) {
    document.getElementById(id).scrollIntoView();
  }
}

【讨论】:

  • 我有同样的问题,scrollIntoView() 适合我!谢谢!
【解决方案3】:

这与 Vue 无关。如果您单击将哈希值设置为某个链接的链接,则滚动离开,然后再次单击同一链接,哈希值不会改变,因此浏览器不会做出反应。没有变化 => 没有反应。

为了解决这个问题,您必须在每个链接上绑定@click.native="hashChecker"。在该函数中,检查event.target.href 是否与当前window.location.hash 匹配。如果它们不匹配,请跳过。

如果它们匹配,则将 window.location.hash 设置为 '#' 并立即返回其初始值。这次窗口将检测到更改并对其做出反应。就是这样,真的。

该函数的示例版本:

hashChecker(e) {
  if (e.target.href === window.location.hash {
    window.location.hash = '#';
    window.location.hash = e.target.href;
  }
}

请记住,此功能有点简单,仅适用于您的情况。如果您的链接有完整的 url(包括域、协议等),您需要先从中提取哈希,然后将其与当前的 window.location.hash 匹配。

您可以将此函数作为方法放置在您使用它的组件中。如果你在多个地方使用它,你可以把它放在一个帮助文件中并从那里导入。由于它不使用this,它可以是静态的或const

【讨论】:

  • 您的 if 始终解析为 true,因为一旦您单击链接,window.location.hash 就会变为 e.target.href。因此函数总是被执行。第一次点击时它可以工作,但我没有解决问题。无论如何谢谢!
  • 如果你在@click.native上绑定hashCheckerhashChecker将在之前默认运行(这就是window.location.hash的变化)。否则,您将无法单击preventdefault()。我认为这很明显,但是您必须将方法绑定到链接:&lt;a href="#some-id" @click.native="hashChecker"&gt;Section with #some-id&lt;/a&gt;
  • @Max,实际上,我在答案中写了@click,这是我的错。应该是@click.native(它是一个锚点,你想捕捉原生点击事件:@click.native。我现在就更正答案。
【解决方案4】:

鉴于我只有有限的时间(老实说,我愿意)继续尝试解决方案,我选择使用 vue-anchor-router-link (https://github.com/mperator/vue-anchor-router-link),它的作用就像一个魅力。非常感谢大家,你们的回答帮助我更好地理解了 Vue 和 Vue Router 处理锚链接的方式。

【讨论】:

    猜你喜欢
    • 2021-11-16
    • 1970-01-01
    • 2019-02-13
    • 2019-06-11
    • 2021-01-06
    • 2018-04-13
    • 1970-01-01
    • 2014-11-21
    • 1970-01-01
    相关资源
    最近更新 更多