滚动到锚点无法正常工作

时间:2016-10-09 08:43:03

标签: angular

尝试使用以下语法滚动到锚链接。

<a [routerLink]="['./']" fragment="test">Testing</a>

锚节点看起来像这样

<div id="test">

单击时,浏览器地址栏会显示#test片段,但不会自动滚动。知道为什么它不滚动吗?

10 个答案:

答案 0 :(得分:18)

基于 @vavav 解决方法并利用片段作为可观察对象提供(使用"@angular/core": "^2.3.1"):

class MyAppComponent implements OnInit{

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    this.route.fragment.subscribe(f => {
      const element = document.querySelector("#" + f)
      if (element) element.scrollIntoView()
    })
  }
}

答案 1 :(得分:3)

我认为滚动还没有用角度2实现。我对类似问题的解决方案(滚动到同一页面上的锚点)是使用ng2-page-scroll

答案 2 :(得分:2)

查看Angular 6新功能ViewportScroller

  

https://angular.io/api/common/ViewportScroller

答案 3 :(得分:1)

我建议用户使用ng2-page-scroll

ng2-page-scroll

安装

npm install ng2-page-scroll --save

导入app.module.ts

import {Ng2PageScrollModule} from 'ng2-page-scroll';

@NgModule({
    imports: [
        /* Other imports here */
        Ng2PageScrollModule
        ]
})
export class AppModule {
}

在你的html组件中测试它

<a pageScroll href="#test">Testing</a>
<div id="test">

答案 4 :(得分:1)

我已经重新创建了一个reusalbe服务,该服务可以在任何组件中使用,以便滚动到片段(如果存在的话)到页面顶部。以下包含通过可重用服务方法在角度锚定中使用的完整回波系统。

//(In service.ts)
import { Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ViewportScroller } from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class RouterPathService {

  constructor(
    private activatedRoute: ActivatedRoute,
    private viewportScroller: ViewportScroller,


  ) { }

  scroll() {
    this.activatedRoute.fragment.subscribe((fragment: string) => {
      if (fragment) {
        this.scrollToAnchor(fragment)
      } else {
        this.scrollToTop();
      }
    });
  }

  scrollToTop() {
    this.viewportScroller.scrollToPosition([0, 0])

  }

  scrollToAnchor(elementId: string): void {
    this.viewportScroller.scrollToAnchor(elementId);
  }
}

我们可以从任何组件的上述可重用服务中调用函数:

//(In component.ts)
......
constructor(
        private routerPathService: RouterPathService,
     
    ) {
        this.routerPathService.scroll();
    }
....

HTML组件需要:

<a [routerLink]="['/my-route']" fragment="test">Testing</a>

app-routing.module.ts应该启用锚定为:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
.........
];

@NgModule({
    imports: [RouterModule.forRoot(routes, {
        anchorScrolling: 'enabled',
    })],
    exports: [RouterModule]
})
export class AppRoutingModule { }

答案 5 :(得分:1)

如果动态加载内容,则ViewportScroller在IE上无法正常工作。

相反,您需要实现AfterViewChecked

TestComponent implements AfterViewChecked{

     ngAfterViewChecked(){
        var element = document.getElementById("youranchor")
        element.scrollIntoView(false)
      }
}

有关详细信息,请参见https://angular.io/api/core/AfterViewChecked

答案 6 :(得分:0)

我喜欢用这个

scroll(container, target) {
    let scrollTo = target.getBoundingClientRect().top;

    $(container).animate({
      scrollTop: `+=${scrollTo}`
    }, 900);
}

然后在HTML中执行类似

的操作
<div #container> <!-- Scrolling container -->
    <button (click)="scroll(container, intro)">Go To Intro</button>
    <!-- other content -->
    <div #intro></div>
</div>

答案 7 :(得分:0)

嗨,使其滚动到Angular v6中:

  1. 在app.module.ts中设置
  imports: [
    RouterModule.forRoot(routes, {
      scrollPositionRestoration: 'enabled',
      anchorScrolling: 'enabled',
      scrollOffset: [0, 64] // [x, y] - adjust scroll offset
    })
  ],
  exports: [RouterModule]

2。

<div id="test">
  // contents goes here...
</div>



<a [routerLink]="['./']" fragment="test" (click)="scrollToAnchor()">Testing</a>
  1. 现在导入viewScroller Angular v6的新功能。
import { ViewportScroller } from '@angular/common';

constructor( private viewportScroller: ViewportScroller ) ...

scrollToTop() { this.viewportScroller.scrollToAnchor('test');}

就是这样!现在点击垃圾邮件进行测试! :P

答案 8 :(得分:0)

这是https://stackoverflow.com/a/52415783/9646878的扩展,具有额外的配置onSameUrlNavigation: 'reload'

对我来说,setTimeout有效。 完整示例:

  1. 在app.module.ts中设置
       imports: [
         RouterModule.forRoot(routes, {
           scrollPositionRestoration: 'enabled', // or 'top'
           anchorScrolling: 'enabled',
           scrollOffset: [0, 64], // [x, y] - adjust scroll offset
           onSameUrlNavigation: 'reload'
         })
       ],
       exports: [RouterModule]
  1. app.component.html
<p>
 <div id = "componentId"> </div>
</p>
  1. app.component.ts
onScrollTo(location: string){
  setTimeout(() => { this.router.navigate([], { fragment: location }); }, 500);
}

在单击按钮时使用此方法。

答案 9 :(得分:0)

我的情况是,在按下屏幕顶部的按钮并从后端接收一些数据后,我可能会收到一条消息,允许滚动到某个点。如果再次按下按钮,我需要能够一次又一次地滚动...

使用成功后

this.viewportScroller.scrollToAnchor

scrollIntoView

在本地,我发现它在生产环境中不起作用(真的不知道为什么)。 所以,

router.navigate([], { fragment: 'yourFragment' });

完成了这项工作,当然我必须“清理”片段以启用未来的滚动,因此我在按钮的逻辑中添加了:

router.navigate(['/']);

重要:记得在 app-routing.module.ts 里面配置 ExtraOptions