点击子锚点滚动到 angular 8 中的父 html 元素单页

Click child anchor scroll to parent html element single page in angular 8

我是 angular 8 的新手并创建了 SPA(单页应用程序),用于菜单栏单独的组件和包含在主组件中的组件。每当单击菜单项(锚元素)时,它应该滚动到 about/contact 元素部分,但我尝试了一些解决方案,但无法滚动。主要是父元素不可访问。

home.component.html

<app-header></app-header>

....

<section #aboutus>About us details</section>

....

<section #contact>Contact form section</section>

header.component.html

<ul>
 <li class="nav-item">
    <a (click)="navigateTo('aboutus')" ><strong>ABOUT</strong></a>
</li>
<li class="nav-item">
    <a (click)="navigateTo('contact')" ><strong>Contact us</strong></a>
</li>
</ul>

header.component.ts

navigateTo(element: string) {
   document.querySelector(''+element+'').scrollIntoView(true);
}

我收到一个错误:

ERROR TypeError: Cannot read property 'scrollIntoView' of null

会有很大帮助。

1 - 将模板引用变量添加到 href 标签,例如:

  <a (click)="navigateTo('aboutus')" #aboutus><strong>ABOUT</strong></a>

2 - 使用 ViewChild 获取 href:

  @ViewChild('aboutus') aboutusLink: ElementRef;

3 - 在此 navigateTo 函数中添加以下内容:

  this.aboutusLink.nativeElement.scrollIntoView({behavior: 'smooth'});

避免在 Angular 中使用原生 js 选择器 :)

这样试试:

Working Demo

home.component.html

<app-header (Navigate)="navigateTo($event)"></app-header>

home.component.ts

  @ViewChild("aboutus", { static: false }) aboutus;
  @ViewChild("contact", { static: false }) contact;

  navigateTo(element: string) {
    this[element].nativeElement.scrollIntoView({ behavior: "smooth" });
  }

header.component.ts

  @Output() Navigate = new EventEmitter();

  navigateTo(element: string) {
    this.Navigate.emit(element)
  }

header.component.html

<ul>
 <li class="nav-item">
    <a (click)="navigateTo('aboutus')" ><strong>ABOUT</strong></a>
</li>
<li class="nav-item">
    <a (click)="navigateTo('contact')" ><strong>Contact us</strong></a>
</li>
</ul>

您可以使用 service 进行高效编码。

// navigate.service.ts

import { Injectable } from '@angular/core';
import { EventEmitter } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class NavigateService {
  navigate = new EventEmmiter<string>();
}

现在HeaderComponent

// header.component.html

<ul>
  <li class="nav-item">
    <a (click)="navigateTo('aboutus')" >
      <strong>ABOUT</strong>
    </a>   
  </li>
  <li class="nav-item">
    <a (click)="navigateTo('contact')" >
      <strong>Contact us</strong>
    </a>
  </li>
</ul>

// header.component.ts

import { Component } from '@angular/core';
import { NavigateService } from 'services/navigate.service'; // set path correctly

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
})
export class HeaderComponent {
  constructor(private navigateService: NavigateService) {}

  navigateTo(status: string): void {
    this.navigateService.navigate.emit(status);
  }
}

最后 HomeComponent

// home.component.html

<app-header></app-header>
....
<section #aboutus>About us details</section>
....
<section #contact>Contact form section</section>

// home.component.ts

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavigateService } from 'services/navigate.service'; // set path correctly

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
})
export class HomeComponent {
  @ViewChild('aboutus', { static: false }) aboutus: ElementRef;
  @ViewChild('contact', { static: false }) contact: ElementRef;

  constructor(private navigateService: NavigateService) {
    this.navigateService.navigate.subscribe((status: string) => {
      this[status].nativeElement.scrollIntoView({ behavior: 'smooth' });
    });
  }
}

现在您可以在需要导航的地方调用该服务。通过使用服务,您可以摆脱重复的额外代码。