**更新**以及接近工作的解决方案:
我正试图让'skip to content'链接跳转到'#content-start'之后的第一个可聚焦元素。
登录-base.component.ts:
import { Component, OnInit } from '@angular/core';
import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class BaseLoginComponent implements OnInit {
constructor(
@Inject(DOCUMENT) private document: any
) {
}
skip() {
console.log(document);
console.log(document.querySelector);
var content = document.querySelector(`#content-start`); // ?? document is null!!
if (content) {
var control = content.querySelector('input, button, a');
console.log(control);
//if (control) {
// control.focus(); // first only
//}
}
};
ngOnInit() {
this.document.getElementById('skipLink').onclick = this.skip;
this.document.getElementById('skipLink').onkeypress = function (e) {
if (e.keyCode == 13) {
this.skip();
}
}
}
}
login.component.html:
<div class="login-page">
<section class="main container" id="content-start">
<input type="text"/>
这实际上有效,因为 console.log(control)返回
<input _ngcontent-c4="" id="username" name="username">
实际上是正确的控制。
但是我不能只设置.focus(),因为我在那里有一个HTML片段,而不是带有方法的对象,例如.focus();
呃,jQuery的$(控制)有角度等价吗?
答案 0 :(得分:1)
正如您所知,skipLink
应该是您的组件类的方法。为了在this
内保持正确的skipLink
,您可以使用addEventListener
和箭头函数设置事件处理程序:
public ngOnInit() {
this.document.getElementById('skipLink').addEventListener("click", () => {
this.skipLink();
});
this.document.getElementById('skipLink').addEventListener("keypress", (e) => {
if (e.keyCode == 13) {
this.skipLink();
}
}
}
private skipLink() {
let control: HTMLElement = this.document.querySelector('input, button, a');
if (control) {
control.focus();
}
}
您可以在this plunker中看到代码正常工作。
正如Kevin所提到的,使用ViewChild
是一种更标准的方式来引用组件中的元素。您可以在目标元素上定义模板引用变量(例如,在下面的组件模板中为#firstButton
),使用ViewChild
获取对它的引用,并使用nativeElement
获取HTML元素本身属性。至于事件处理程序,您可以使用Angular绑定设置它们(例如(click)="skipLink()"
)。
该方法显示在this plunker:
中import { Component, NgModule, Inject, ElementRef, ViewChild } from '@angular/core';
...
@Component({
selector: 'my-app',
template: `
<button #firstButton>Focusable Button</button>
<br/>
<button (click)="skipLink()">Click here to set focus on first button</button>
`,
...
})
export class App {
@ViewChild("firstButton") private firstButton: ElementRef;
private skipLink() {
this.firstButton.nativeElement.focus();
}
}
答案 1 :(得分:0)
这种情况正在发生,因为尚未在ngOnInit
中加载DOM。将代码更新为这样,实现AfterViewInit
:
export class AppComponent implements AfterViewInit{
constructor(
@Inject(DOCUMENT) private document: any
) { }
}
ngAfterViewInit() {
this.document.getElementById('skipLink').onclick = skipLink;
this.document.getElementById('skipLink').onkeypress = function (e) {
if (e.keyCode == 13) {
skipLink();
}
}
function skipLink() {
let content: HTMLElement = this.document.querySelector("#content-start"); // ?? document is null!!
if (content) {
let control: HTMLElement = this.document.querySelector('input, button, a');
console.log(control);
if (control) {
// control.focus(); // first only
}
}
}
}
ngAfterViewInit
听起来确实如此;它只在最初加载视图时运行。
编辑以回答您的问题:您正在寻找angular.element。关于它的文档非常有用,并且是在Angular中操作元素的更好的编程实践。
答案 2 :(得分:0)
这已经远离最初的实施;如果我更新开场白,那么评论就毫无意义了。
按照凯文的建议按照U sing ViewChild in Angular to Access a Child Component, Directive or DOM Element实施,(除非我误解):
xvar
import { Component, ViewChild, AfterViewInit, ElementRef } from '@angular/core';
export class AppComponent {
@ViewChild('firstControl') firstControl: ElementRef;
skipLink() {
console.log(this.firstControl);
//if (this.firstControl) { this.firstControl.focus(); }
};
不幸的是,这并不是更好。 this.firstControl未定义。