简体   繁体   English

如何从另一个同级组件(​​跳过链接)定位 Angular 中的 html 元素?

[英]How do I target an html element in Angular from another sibling component (skip link)?

I need to target a nested layout component's element from another sibling component.我需要从另一个同级组件中定位嵌套布局组件的元素。 The desired target element is several layers deep within said component.所需的目标元素位于所述组件内的几层深处。 I Have a Header Component that is housing a Skip Link <a></a> .我有一个包含跳过链接<a></a>Header组件。 Upon selecting the Skip Link I need to send focus to the aforementioned sibling component's #main-content element, which happens to be a <div></div> .选择跳过链接后,我需要将focus发送到上述兄弟组件的#main-content元素,它恰好是一个<div></div> How can I achieve this?我怎样才能做到这一点?

I have tried creating a custom attribute directive.我曾尝试创建自定义属性指令。 I have tried targeting the element with @ViewChild("main-content") , I can't seem to get the target element to achieve focus, and thus show the border with style changes.我尝试使用@ViewChild("main-content")定位元素,我似乎无法让目标元素获得焦点,从而显示带有样式更改的边框。 Any Advice is greatly appreciated.任何意见是极大的赞赏。

Header Component:标题组件:

...
<a [href]="skipLinkPath" class="skip-link" (click)="skipLink()" tabIndex="0">Skip to Main Content</a> 
...

Header Component's TS:标题组件的 TS:

...
@ViewChild('#mainContent') mainContent: ElementRef;

...

skipLink() {
  console.log("click event called");
  console.log(this.mainContent);
  this.mainContent.nativeElement.focus();
} 
...

Main Component:主要组件:

  <div class="content-display skip-link-focus" role="main"  id="main-content" #mainContent>
    <router-outlet></router-outlet>
  </div>

You can use a shared service to achive this您可以使用共享服务来实现此目的

SharedService.ts -> SharedService.ts ->

isFocus: Subject<boolean> = new Subject<boolean>();

Create a subject in shared service在共享服务中创建主题

Header Component标题组件

skipLink() {
  this.sharedService.isFocus.next(true);
}

Main Component create a field主组件创建一个字段

isFocus = false;

in on init method subscribe to service在 init 方法中订阅服务

this.sharedService.isFocus.subscribe(value => {
    this.isFocus = value;
});



  <div class="content-display skip-link-focus" role="main" [ngClass]={_focused: isFocus}  id="main-content" #mainContent>
    <router-outlet></router-outlet>
  </div>

in css在 CSS 中

._focused {
 //required css
}

Not entirely sure why the accepted answer is JavaScript based.不完全确定为什么接受的答案是基于 JavaScript 的。 This can all be achieved with no JS at all in a much simpler fashion and more robust way.这一切都可以在完全没有 JS 的情况下以更简单的方式和更健壮的方式实现。

<a [href]="skipLinkPath" class="skip-link" (click)="skipLink()" tabIndex="0">Skip to Main Content</a> 

Firstly the skip link shouldn't need a tabindex , if you needed to add that to make the link accessible have a quick look through your code for an issue as links are automatically added to the focus order.首先,跳过链接不应该需要tabindex ,如果您需要添加它以使链接可访问,请快速浏览您的代码以查找问题,因为链接会自动添加到focus顺序中。

The above could become:以上可以变成:

<a [href]="#main-content" class="skip-link">Skip to Main Content</a> 

Notice how I changed the href to match the id of your main content div.请注意我如何更改href以匹配您的主要内容 div 的 id。

  <div class="content-display" role="main"  id="main-content" #mainContent>
    <router-outlet></router-outlet>
  </div>

The above will work without needing to handle the focus state yourself (if you want the main div to show that it is focused add tabindex="0" to it, but the above example will still skip the menu with the next tab stop being the first focusable item in your HTML).上面不需要自己处理焦点状态就可以工作(如果你想让主 div 显示它是焦点,添加tabindex="0"到它,但上面的例子仍然会跳过菜单,下一个制表位是HTML 中的第一个可聚焦项)。

What about the URL change using an anchor?使用锚点更改 URL 怎么样?

Obviously the above adds a #main-content to your URL, I don't consider that an issue, but if you do, you could intercept the click and use the history API in the browser to stop the URL updating.显然,上面在您的 URL 中添加了#main-content ,我不认为这是一个问题,但是如果您这样做了,您可以拦截点击并使用浏览器中的历史 API 来停止 URL 更新。

Although that may then seem like more work, you then have a functional skip link that works without JavaScript so that whatever no JavaScript fallback your site has is still accessible.尽管这看起来似乎需要更多的工作,但您将拥有一个无需 JavaScript 即可工作的功能性跳过链接,以便您的网站仍然可以访问没有 JavaScript 后备的任何内容。

final suggestion最后的建议

  <div class="content-display" role="main"  id="main-content" #mainContent>

The above div looks like it could be changed to a <main> element to be more semantically correct as I am assuming you are using HTML5 .上面的 div 看起来可以更改为<main>元素以在语义上更正确,因为我假设您使用的是HTML5

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Angular 4 如何在同级模块组件中使用其他模块组件 - Angular 4 How do I use another modules components in a sibling modules component 从Angular 2+中的同级组件访问元素 - Accessing an element from sibling component in Angular 2+ 如何访问Angular中另一个组件的DOM元素? - How do I access the DOM element of another component in Angular? 如何在 Angular 中将数据从一个组件发送到另一个组件? - How do I send data from a Component to another Component in Angular? 如何从 React 中的另一个兄弟组件触发兄弟组件 function? - How to trigger sibling component function from another sibling component in React? Angular2:从组件中获取兄弟组件模板中的元素 - Angular2 : get hold of an element in template of a sibling component from a component 我如何共享一个兄弟姐妹的功能到另一个兄弟姐妹的组件 - how can i share function of one sibling to another sibling component 在 angular 8 中,我们如何将数据从一个组件发送到另一个同级组件? - How we send data from one component to another sibling component in angular 8? 目标 Bootstrap HTML 元素,其中 data-bs-target 来自 Angular 中的另一个元素 - Target Bootstrap HTML element with data-bs-target from another element in Angular 如何在 angular 中将表单数据从一个组件保存到另一个组件? - How do I persist formdata from one component to another in angular?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM