【问题标题】:Using HTML anchor link #id in Angular 6在 Angular 6 中使用 HTML 锚链接#id
【发布时间】: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

【问题讨论】:

    标签: html angular routes anchor hash-location-strategy


    【解决方案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 解决方案都在不断发展
      猜你喜欢
      • 2011-08-10
      • 1970-01-01
      • 2020-08-27
      • 2017-09-02
      • 2012-03-09
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多