在Angular 6中,锚点滚动仅在第二次点击时起作用。

3

我有一个非常基础的设置在一个非常长的页面上:

<a href="/technicalmanagerreport/4e8485d9-5751-4684-9d24-0af2934dd390#h2">test</a>
<h2 id="h2">LOL</h2>

第一次点击链接时,它会快速跳转并返回顶部。第二次点击时,它就可以正常工作了。如果我先点击链接,然后点击另一个链接,再次点击该链接,则会出现相同的行为。因此需要连续两次点击才能正常工作。有什么想法或者解决方法吗?
经过更多的搜索:
<a href="technicalmanagerreport/4e8485d9-5751-4684-9d24-0af2934dd390#lol">test</a>

 <div *ngFor="let group of report?.assetGroups">

    <div><a href="technicalmanagerreport/4e8485d9-5751-4684-9d24-0af2934dd390#{{group?.code}}">{{group.name}}</a></div>
 </div>


<div *ngFor="let group of report?.assetGroups">
    <div id="{{group?.code}}">{{group?.name}}</div>
    <div *ngFor="let subGroup of group?.assetSubGroupList">
        <h4>{{subGroup.name}}</h4>
      </div>
</div>

<div id="lol">lol</div>

测试链接按预期工作。可能是由于从调用REST服务(异步调用)返回的其他值有问题?


奇怪。你是否使用了其他可能会冲突的库? - Phix
我正在使用CoreUI,但我可以尝试在一个新的空的Angular项目中进行测试。 - Thomas Segato
如果您查看我的初始帖子,它仅适用于动态计算的链接。我还注意到当我悬停在链接上时,它首先是technicalmanagerreport/4e8485d9-5751-4684-9d24-0af2934dd390#...,然后在一两秒钟后计算出值。就像Angular对该值进行了一些延迟计算。当我第一次单击时可能也适用相同的情况,正在计算值。这就是为什么第二次有效的原因? - Thomas Segato
不对,它也带有静态链接。其他页面都能用。这个页面很大,可能是因为元素太多了吗? - Thomas Segato
你使用的 Angular 版本是哪个? - Chellappan வ
我有一个类似的问题...我发现页面在URL更改时会刷新,因此出现异常行为。对于这个问题的答案对我没有用。 - Rahul Gala
3个回答

1

我在技术上无法重现这个问题,但可能的原因是您没有正确实现HashLocationStrategy,或者可能正在使用PathLocationStrategy,正如此参考文献中所述:Angular Routing Navigation

这个问题的解决方法可能是:

选项1:使用片段

在您的HTML文件中:

<a [routerLink]="['/']" fragment="h2"></a>

在你的Typescript文件中。
 ngOnInit() {
     this.route.fragment.subscribe(fragment => { this.fragment = fragment; });
    }

    ngAfterViewChecked(): void {
      try {
          if(this.fragment) {
              document.querySelector('#' + this.fragment).scrollIntoView();
          }
      } catch (e) { }
    }

选项2:只需创建方法并滚动
在您的HTML文件中:
<button (click)="scroll(target)"></button>
<div #target>Your target</div>

在你的 .ts 文件中。
scroll(el) {
    el.scrollIntoView({ behavior: "smooth"});
}

谢谢,非常感谢。我会尝试一下。然而,我还发现了一些问题。如果您查看我的初始页面,您会发现我在同一页上有一个可用的链接。我开始相信这可能与来自异步源的链接有关? - Thomas Segato
我非常喜欢你的第二个选项,这样我就不必生成一个 URL 了。你知道怎么动态执行这个操作吗?我尝试了 <div (click)="scroll(group.code)">{{group.name}}</div><div #{{group.code}} id="{{group?.code}}">{{group?.name}}</div> ,但都没有成功。 - Thomas Segato
也许你可以尝试使用ng-container和ngFor循环,如此处所述 > 链接 - Richard Pariath
1
我认为这一切都与另一个问题有关。我刚刚尝试了你的第一种选项,但是出现了以下错误:ERROR DOMException: Failed to execute 'querySelector' on 'Document': '#1000' is not a valid selector。我将为此创建另一篇帖子。感谢您的帮助。 - Thomas Segato
由于Angular不直接允许DOM渲染,因此您无法使用querySelector。您需要从@angular/core导入ElementRef并使用它和Angular的Render2。您可以参考链接 - Richard Pariath

1

我能找到的唯一解决方法是将滚动函数包裹在一个setTimeOut函数中。虽然这不是最佳实践,但这种方法确保解决了问题。

  scroll(link: string) {
  window.location.href = this.href + '#' + link;
  setTimeout(() => {document.querySelector('#' + link).scrollIntoView()}, 0);

}


0
如果你使用了scrollPositionRestoration: 'enabled',那么你应该在下面添加这行代码。
    anchorScrolling: 'enabled'

在 app.module.ts 脚本中
示例:
@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, RouterModule.forRoot(routes, {
        scrollPositionRestoration: 'enabled',
        anchorScrolling: 'enabled' // ------->   Add this Line
    }), ComponentsModule],
    providers: [],
    bootstrap: [AppComponent],
    schemas: [CUSTOM_ELEMENTS_SCHEMA],
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接