在 Angular 6 中使用 HTML 锚链接#id

Posted

技术标签:

【中文标题】在 Angular 6 中使用 HTML 锚链接#id【英文标题】:Using HTML anchor link #id in Angular 6 【发布时间】:2018-11-22 23:49:03 【问题描述】:

我正在处理一个 Angular 6 项目,在该项目中我禁用/删除了从 URL 中删除 # 的 hash-location-strategy。

由于此更改,链接具有:

<li routerLinkActive="active">
   <a [routerLink]="['/settings']">Contact Settings</a>
   <ul class="child-link-sub">
      <li>
         <a href="#contactTypes">Contact Types</a>
      </li>
   </ul>
</li>

不再起作用,它只是跳过当前组件 URL 并将 #contactTypes 放在 localhost 之后。

我发现这个github issue 应该可以解决这个问题

<a [routerLink]="['/settings/']" fragment="contactTypes" >Contact Types</a>

将 #contactTypes 放在 URL 的末尾,但不会滚动到浏览器的顶部。

来源:https://github.com/angular/angular/issues/6595

【问题讨论】:

【参考方案1】:

这对我有用(我使用的是 Angular 12.1.3):

html 模板上:

<a (click)="scrollTo('anchorId')">Scroll to another position</a>

将要滚动到的元素的 ID(不带标签符号 #)传递给函数。

然后,在 Typescript 上,使用 .scrollIntoView 使浏览器滚动到该元素的位置。

scrollTo(element: any): void 
  (document.getElementById(element) as HTMLElement).scrollIntoView(behavior: "smooth", block: "start", inline: "nearest");

【讨论】:

【参考方案2】:

这是针对 Angular 9 的,但我相信社区会从中受益,

您可以在@angular/common 中使用Location 来获取当前路径。

假设您有以下带有要关注的 id 的元素

&lt;div id="bring-me-to-the-focus"&gt;

我这里只展示提取的代码块。

import  Location  from '@angular/common';

constructor(private location: Location)  

this.location.path() + '#bring-me-to-the-focus'; 

我相信这会对某人有所帮助:)

干杯。

【讨论】:

我不认为这是必要的,因为路由器通过anchorScrollingonSameUrlNavigation 提供此功能【参考方案3】:

正如 Nitin Avula 在 comment 中指出的那样,仅当您导航到不同的路由或在路由器配置中启用了 onSameUrlNavigation 时,使用 routerLink 作为哈希锚才有效。

解决这个问题的一种方法是去掉routerLink,而是在*.component.ts 文件中使用this.router.navigatefragment 参数:

HTML -

<a (click)="scrollToContactTypes()">Contact Types</a>

TypeScript -

constructor(private router: Router)  

scrollToContactTypes() 
    this.router.onSameUrlNavigation = "reload";
    this.router.navigate(["/settings"],  fragment: "contactTypes" ).finally(() => 
        this.router.onSameUrlNavigation = "ignore"; // Restore config after navigation completes
    );

【讨论】:

如果您出于某种原因假装允许onSameUrlNavigation = "reload" IDK,那么有趣的答案【参考方案4】:

出于可访问性的原因,我不得不在文档开头提供一个链接,以便使用屏幕阅读器为用户提供对内容的直接访问,从而跳过页面中重复的页面部分。

因为我需要链接保持焦点(最好保留 href 属性),因为我实际上是在 app-root 或任何组件之外(仍然解决方案在组件内工作),为此我使用了简单的老式 html和javascript

<a href="./#content"
     onclick="event.preventDefault(); location.hash='content';"
     class="content-shortcut"
     title="Access page content directly"
     i18n-title
     aria-label="Access page content directly"
     i18n-label>Access page content directly</a>
  <style>
    .content-shortcut 
      position: absolute;
      opacity: 0;
      height: 0px;
      font-size: 1px;
    

    .content-shortcut:focus,
    .content-shortcut:active 
      position: relative;
      opacity: 1;
      height: auto;
      font-size: 1em;
      display: block;
      color: black;
      background: white;
    

  </style>

【讨论】:

这也是我必须做的,谢谢你的帖子 满足 WCAG 要求跳过主导航的最佳解决方案。非常简单和优雅。谢谢!【参考方案5】:

Angular 6.1 带有一个名为anchorScrolling 的选项,它位于路由器模块的ExtraOptions 中。正如anchorScrolling definition 所说:

配置当 url 有片段时路由器是否应该滚动到元素。

'disabled' -- 什么都不做(默认)。

'enabled' -- 滚动到元素。此选项将在未来成为默认选项。

“popstate”上不会发生锚点滚动。相反,我们恢复存储的位置或滚动到顶部。

你可以这样使用它:

const routerOptions: ExtraOptions = 
  useHash: false,
  anchorScrolling: 'enabled',
  // ...any other options you'd like to use
;

// then just import your RouterModule with these options

RouterModule.forRoot(MY_APP_ROUTES, routerOptions)

【讨论】:

感谢您的回答。我错过的是你必须使用 routerLink="./" fragment="anchorName" 你不能使用 href="#anchorName" 另外,这仅适用于第一次点击。 2号不行。 要在第二次点击时工作,您需要在 routerOptions 中添加 onSameUrlNavigation: 'reload' 选项。 为了让这个解决方案发挥作用,我还必须添加 angular.io/api/router/ExtraOptions#scrollPositionRestoration ^^^ 已确认,这也适用于 Angular 11。上面提到的所有选项也都有效,即anchorScrolling: 'enabled', onSameUrlNavigation: 'reload', scrollPositionRestoration: 'enabled'【参考方案6】:

使用ngx page scroll

 <a pageScroll href="#awesomePart">Take me to the awesomeness</a>
 <h2 id="awesomePart">This is where the awesome happens</h2>

【讨论】:

很好的答案,它运作良好。例如,如果您在 /home 页面中,则需要执行 href="home#anchor"。 +1 你不需要一个库,这个行为包含在角度路由器中。【参考方案7】:

您需要使用哈希路由策略来启用哈希滚动。

您需要将第二个参数作为 RouterModule.forRoot([],useHash:true 之类的对象提供。它会起作用。

【讨论】:

哈希策略将哈希作为路由处理,不是吗?【参考方案8】:

我正在寻找类似的解决方案并尝试使用 ngx-scroll-to 包,发现它在最新版本的 angular 中不起作用,因此决定研究其他选项并发现我们可以使用 scrollIntoView

HTML 代码:

<button (click)="scrollToElement(target)"></button>
<div #target>Your target</div>

Ts 代码:

  scrollToElement($element): void 
    console.log($element);
    $element.scrollIntoView(behavior: "smooth", block: "start", inline: "nearest");
  

【讨论】:

谢谢,您的回答非常好,而且代码简单易懂 能否提供动态链接?为此目的还有其他答案,但代码并不简单 这并不理想,因为它没有为用户提供可以与他人共享的链接,例如“example.org/help#installing”。 @ANeves 是的,现在“这并不理想”,但是当我回答问题时,achorScrolling 的该功能不可用。因为 angular 6.1 是后来发布的。这个解决方案可能对那些使用旧版本 angular 的人有帮助。很棒的是,随着每个新版本的 angular 解决方案都在不断发展

以上是关于在 Angular 6 中使用 HTML 锚链接#id的主要内容,如果未能解决你的问题,请参考以下文章

Angular2将纯文本转换为url的方式(锚链接)

如何在 react-router 中使用普通的锚链接

使用jQuery滚动到锚链接[重复]

使用jQuery滚动到锚链接[重复]

vue中的锚链接跳转问题

vue中的锚链接跳转问题