[英]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 中的第一个可聚焦项)。
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 后备的任何内容。
<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.