Html Angular4 - 滚动到锚点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44441089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 14:43:42  来源:igfitidea点击:

Angular4 - Scrolling to anchor

htmlcssangularanchor-scroll

提问by lnamba

I am trying to do a simple scroll to an anchor element on the same page. Basically, the person clicks on a "Try It" button and it scrolls to an area lower on the page with the id "login". Right now, it is working with a basic id="login"& <a href="#login"></a>but it is jumping to that section. Ideally, I would like it to scroll there. If I am using Angular4, is there some built in way to do this or what is the easiest way? Thanks!

我正在尝试对同一页面上的锚元素进行简单的滚动。基本上,用户单击“尝试”按钮,然后滚动到页面下方带有“登录”ID 的区域。现在,它正在使用基本的id="login"&<a href="#login"></a>但它正在跳转到该部分。理想情况下,我希望它在那里滚动。如果我使用的是 Angular4,是否有一些内置的方法可以做到这一点,或者什么是最简单的方法?谢谢!

Whole template... (component still empty)

整个模板...(组件仍然是空的)

<div id="image-header">
    <div id="intro">
        <h1 class="text-center">Welcome to ThinkPlan</h1>
        <h3 class="text-center">Planning your way</h3>
        <a class="btn btn-outline-primary" href="#login" id="view">Try It</a> <!-- Where the user clicks to scroll -->
    </div>
</div>
<div class="container" id="info">
    <div class="row">
        <div class="col-md-12">
             <div class="space" id="login"></div> <!-- The place to scroll to -->
                <h1 class="text-center">ThinkPlan</h1>
                <form  class="form-horizontal">
                    <fieldset>
                        <legend>Login</legend>
                        <div class="form-group">
                            <label for="inputEmail" class="col-lg-2 control-label">Email</label>
                            <div class="col-lg-10">
                                <input type="text" class="form-control" id="inputEmail" placeholder="Email">
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputPassword" class="col-lg-2 control-label">Password</label>
                            <div class="col-lg-10">
                                <input type="password" class="form-control" id="inputPassword" placeholder="Password"> 
                            </div>
                        </div>
                        <div class="form-group" id="log-btn">
                            <div class="col-lg-10 col-lg-offset-2">
                                <button routerLink="/plan" type="submit" class="btn btn-outline-primary">Login</button>
                            </div>
                        </div>
                        <p class="lead text-center">New here? <a routerLink="signup">Sign up.</a></p>
                    </fieldset>
                </form>
        </div>
    </div>
</div>

回答by Sarah Dubois

I think it's more simple solution :

我认为这是更简单的解决方案:

In your HTML :

在您的 HTML 中:

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

In your typescript :

在你的打字稿中:

ngOnInit() {
 this.route.fragment.subscribe(fragment => { this.fragment = fragment; });
}

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

回答by 0lukasz0

For Angular 6+ you can use:

对于 Angular 6+,您可以使用:

  1. In your routing module:

     imports: [RouterModule.forRoot(routes, { anchorScrolling: 'enabled'})]
    
  2. Then in your component html

     <a (click)="onClick('AnchorId')">Click me!</a>
     <a (click)="onClick('OtherAnchorId')">Click me, too!</a>
     ...
     <div id="AnchorId">...</div>
     ...
     <div id="OtherAnchorId">...</div>
    
  3. Then in your component ts

    import { ViewportScroller } from '@angular/common';
    
    @Component({
        selector: 'component-selector',
        templateUrl: './mycomponent.component.html'
    })
    export class MyComponent {
      constructor(private viewportScroller: ViewportScroller) {}
    
      public onClick(elementId: string): void { 
          this.viewportScroller.scrollToAnchor(elementId);
      }
    }
    
  1. 在您的路由模块中:

     imports: [RouterModule.forRoot(routes, { anchorScrolling: 'enabled'})]
    
  2. 然后在你的组件 html

     <a (click)="onClick('AnchorId')">Click me!</a>
     <a (click)="onClick('OtherAnchorId')">Click me, too!</a>
     ...
     <div id="AnchorId">...</div>
     ...
     <div id="OtherAnchorId">...</div>
    
  3. 然后在你的组件 ts

    import { ViewportScroller } from '@angular/common';
    
    @Component({
        selector: 'component-selector',
        templateUrl: './mycomponent.component.html'
    })
    export class MyComponent {
      constructor(private viewportScroller: ViewportScroller) {}
    
      public onClick(elementId: string): void { 
          this.viewportScroller.scrollToAnchor(elementId);
      }
    }
    

回答by Kim Kern

Automatic Scrolling

自动滚动

Since Angular v6, there is the new anchorScrollingoption for the RouterModule. You can set it in the module's import:

由于角V6,还有就是新anchorScrolling的选项RouterModule。您可以在模块的导入中设置它:

imports: [
  ...,
  RouterModule.forRoot(routes, {anchorScrolling: 'enabled'})

With this, Angular will automatically scroll to the element with the id of the given fragment.

这样,Angular 将自动滚动到具有给定片段 id 的元素。

?? However, this does not work when the data is loaded asynchronously, see this Github issue. ??

?? 但是,这在异步加载数据时不起作用,请参阅此Github 问题。??



Manual Scrolling

手动滚动

Smooth scrollingis not yet possible via the RouterModule, but you can do it manually:

还不能通过平滑滚动RouterModule,但您可以手动进行:

1) Get your target e.g. with ViewChild:

1) 获得您的目标,例如ViewChild

@ViewChild('pageInfo') pageInfo: ElementRef; 

2) Call scrollIntoViewon the nativeElement:

2)调用scrollIntoViewnativeElement

const targetElement = this.pageInfo.nativeElement
targetElement.scrollIntoView({behavior: "smooth"})

回答by Sergey Andreev

AfterViewCheck()will be called every time the ChangeDetectionis triggered, so it is a bad solution.

AfterViewCheck()每次ChangeDetection触发都会被调用,所以这是一个糟糕的解决方案。

Use AfterViewInit()like

使用AfterViewInit()喜欢

public ngAfterViewInit(): void {
  this.subscription = this.route.fragment
    .subscribe(fragment => {
        const targetElement = this.document.querySelector('#' + fragment);
        if (fragment && targetElement) {
            targetElement.scrollIntoView();
        } else {
            window.scrollTo(0, 0);
        }
    });
}
public ngOnDestroy(): void {
    this.subscription.unsubscribe();
}

回答by Gianluca Beritognolo

With Angular 4 you can have some problem using anchor to the same page.

使用 Angular 4,您在使用锚点到同一页面时可能会遇到一些问题。

I solved using this way

我用这种方式解决了

ng2-page-scroll

ng2-page-scroll

install

安装

npm install ng2-page-scroll --save

import in your app.module.ts

在你的 app.module.ts 中导入

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

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

test it in your html component

在你的 html 组件中测试它

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

回答by Aleksandr Skobeltcyn

Finally, works for me in Angular 7:

最后,在 Angular 7 中对我有用:

Html:

网址:

<h1 id='here'>Here</h1>

Component:

成分:

  ngAfterViewInit() {
    this.route.fragment.subscribe(fragment => {
      this.fragment = fragment;
      setTimeout(() => this.scrollToAnchor(), 10);
    });
  }

  scrollToAnchor(): void {
    try {
      if (this.fragment) {
        document.querySelector('#' + this.fragment).scrollIntoView();
      }
    } catch (e) { }
  }
  goToHere():void{
    this.router.navigate(['/product'], { fragment: 'here' });
  }

回答by Ian Poston Framer

This is a more detailed example to add to Sarah Dubois' answer above.

这是一个更详细的例子,可以添加到上面 Sarah Dubois 的回答中。

Import router modules.

导入路由器模块。

import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';

import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';

constructor(private route:ActivatedRoute, 
            private router:Router) {

  router.events.subscribe(event => {
    if (event instanceof NavigationEnd) {    
      if (event.url) {
        this.route.fragment.subscribe(fragment => this.fragment = fragment);
      }
    }
  });

}

ngAfterViewChecked(): void {

  try {
    if(this.fragment != null) {
     document.querySelector("a[name="+this.fragment+"]").scrollIntoView();
    }
  } catch (e) {
    //console.log(e, 'error');
  }

}

I like the use of querySelector which will give you a lot of options to which element you would like to scroll to. https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

我喜欢 querySelector 的使用,它会给你很多选择你想要滚动到哪个元素的选项。https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

This works with Angular 8 :)

这适用于 Angular 8 :)