초점설정에 합니다.
저는 Angular 5로 프런트 엔드 애플리케이션을 하고 있는데 검색 상자를 숨겨야 하는데 버튼을 클릭하면 검색 상자가 표시되고 초점이 맞춰져야 합니다.
StackOverflow에서 디렉티브 등으로 몇 가지 방법을 찾아봤지만 성공할 수 없습니다.
다음은 샘플 코드입니다.
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello</h2>
</div>
<button (click) ="showSearch()">Show Search</button>
<p></p>
<form>
<div >
<input *ngIf="show" #search type="text" />
</div>
</form>
`,
})
export class App implements AfterViewInit {
@ViewChild('search') searchElement: ElementRef;
show: false;
name:string;
constructor() {
}
showSearch(){
this.show = !this.show;
this.searchElement.nativeElement.focus();
alert("focus");
}
ngAfterViewInit() {
this.firstNameElement.nativeElement.focus();
}
검색 상자가 포커스로 설정되지 않았습니다.
내가 어떻게 그럴 수 있을까?
2022년 편집:
아래의 @Cichy의 대답으로 더 현대적인 방법을 읽으십시오.
다음과 같이 검색 방법 표시 수정
showSearch(){
this.show = !this.show;
setTimeout(()=>{ // this will make the execution after the above boolean has changed
this.searchElement.nativeElement.focus();
},0);
}
이 경우 HTML 자동 포커스를 사용해야 합니다.
<input *ngIf="show" #search type="text" autofocus />
참고: 구성 요소가 지속되어 재사용되는 경우 조각이 처음 부착될 때만 자동 포커스가 설정됩니다.이 문제는 글로벌 DOM 수신기가 연결될 때 DOM 조각 내부에서 자동 포커스 특성을 확인한 다음 JavaScript를 통해 다시 적용하거나 포커스를 지정하여 해결할 수 있습니다.
다음은 글로벌 리스너의 예로, 스파 애플리케이션에 한 번만 배치하면 동일한 조각이 재사용되는 횟수에 관계없이 자동 포커스가 작동합니다.
(new MutationObserver(function (mutations, observer) {
for (let i = 0; i < mutations.length; i++) {
const m = mutations[i];
if (m.type == 'childList') {
for (let k = 0; k < m.addedNodes.length; k++) {
const autofocuses = m.addedNodes[k].querySelectorAll("[autofocus]"); //Note: this ignores the fragment's root element
console.log(autofocuses);
if (autofocuses.length) {
const a = autofocuses[autofocuses.length - 1]; // focus last autofocus element
a.focus();
a.select();
}
}
}
}
})).observe(document.body, { attributes: false, childList: true, subtree: true });
이 지시어는 표시되는 즉시 요소의 텍스트에 초점을 맞추고 선택합니다.일부 경우에는 setTimeout이 필요할 수 있으며, 테스트를 많이 거치지 않았습니다.
import { Directive, ElementRef, OnInit } from '@angular/core';
@Directive({
selector: '[appPrefixFocusAndSelect]',
})
export class FocusOnShowDirective implements OnInit {
constructor(private el: ElementRef) {
if (!el.nativeElement['focus']) {
throw new Error('Element does not accept focus.');
}
}
ngOnInit(): void {
const input: HTMLInputElement = this.el.nativeElement as HTMLInputElement;
input.focus();
input.select();
}
}
HTML의 경우:
<mat-form-field>
<input matInput type="text" appPrefixFocusAndSelect [value]="'etc'">
</mat-form-field>
구성 요소의 html:
<input [cdkTrapFocusAutoCapture]="show" [cdkTrapFocus]="show">
구성 요소 컨트롤러:
showSearch() {
this.show = !this.show;
}
..A11yModule을 @angular/cdk/a11y에서 가져오는 것도 잊지 마십시오.
import { A11yModule } from '@angular/cdk/a11y'
저는 이 문제를 고려할 것입니다(Angular 7 Solution)
input [appFocus]="focus"....
import {AfterViewInit, Directive, ElementRef, Input,} from '@angular/core';
@Directive({
selector: 'input[appFocus]',
})
export class FocusDirective implements AfterViewInit {
@Input('appFocus')
private focused: boolean = false;
constructor(public element: ElementRef<HTMLElement>) {
}
ngAfterViewInit(): void {
// ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
if (this.focused) {
setTimeout(() => this.element.nativeElement.focus(), 0);
}
}
}
이것은 setTimeout 없이 iAngular 8에서 작동합니다.
import {AfterContentChecked, Directive, ElementRef} from '@angular/core';
@Directive({
selector: 'input[inputAutoFocus]'
})
export class InputFocusDirective implements AfterContentChecked {
constructor(private element: ElementRef<HTMLInputElement>) {}
ngAfterContentChecked(): void {
this.element.nativeElement.focus();
}
}
설명:자, 이것이 작동하는 이유는 변화 감지 때문입니다.setTimeout이 작동하는 이유와 동일하지만, Angular에서 setTimeout을 실행하면 Zone.js를 바이패스하여 모든 검사를 다시 실행하고 setTimeout이 완료되면 모든 변경이 완료되므로 작동합니다.올바른 라이프사이클 후크(AfterContentChecked)를 사용하면 동일한 결과를 얻을 수 있지만 추가 사이클이 실행되지 않는다는 장점이 있습니다.이 기능은 모든 변경사항을 확인하고 통과하면 실행되며, 내용 후 후크 이후에 실행됩니다.Init 및 DoCheck.여기서 제가 틀렸다면 고쳐주세요.
https://angular.io/guide/lifecycle-hooks 에서 라이프사이클 및 변경 감지 기능을 하나 더 제공합니다.
업데이트: A11y 패키지인 Angular Material CDK를 사용하는 경우 훨씬 더 좋은 방법을 찾았습니다.먼저 입력 필드가 있는 구성 요소를 선언하는 모듈에서 A11yModule을 가져옵니다.그런 다음 cdkTrapFocus 및 cdkTrapFocus를 사용합니다.AutoCapture 명령어는 HTML에서 다음과 같이 사용하고 입력에 tabIndex를 설정합니다.
<div class="dropdown" cdkTrapFocus cdkTrapFocusAutoCapture>
<input type="text tabIndex="0">
</div>
우리는 우리의 드롭다운에 위치와 반응성에 몇 가지 문제가 있었고 대신 cdk의 OverlayModule을 사용하기 시작했고, A11yModule을 사용한 이 방법은 완벽하게 작동합니다.
Angular에서 HTML 자체 내에서 버튼을 클릭하면 입력하도록 포커스를 설정할 수 있습니다.
<button (click)="myInput.focus()">Click Me</button>
<input #myInput></input>
부울이 변경된 후 실행하고 시간 초과 사용을 방지하려면 다음을 수행할 수 있습니다.
import { ChangeDetectorRef } from '@angular/core';
constructor(private cd: ChangeDetectorRef) {}
showSearch(){
this.show = !this.show;
this.cd.detectChanges();
this.searchElement.nativeElement.focus();
}
저도 같은 시나리오를 쓰고 있습니다. 이것은 저에게 효과가 있었지만, 저는 당신이 가지고 있는 "숨기기/보기" 기능을 가지고 있지 않습니다.따라서 필드를 항상 볼 수 있을 때 먼저 포커스가 있는지 확인한 다음, 가시성을 변경할 때 작동하지 않는 이유를 해결하려고 시도할 수 있습니다(아마도 그렇기 때문에 수면 또는 약속을 적용해야 할 것입니다)
포커스를 설정하려면 다음과 같이 변경해야 합니다.
HTML 매트 입력은 다음과 같아야 합니다.
<input #yourControlName matInput>
TS 클래스에서 변수 섹션에서 이와 같은 참조(
export class blabla...
@ViewChild("yourControlName") yourControl : ElementRef;
버튼을 누르면 됩니다. 전화하세요.
showSearch(){
///blabla... then finally:
this.yourControl.nativeElement.focus();
}
그리고 이것이 마지막입니다.제가 찾은 이 게시물에서 이 솔루션을 확인하실 수 있습니다. 덕분에 --> https://codeburst.io/focusing-on-form-elements-the-angular-way-e9a78725c04f
DOM성있다라는 DOM .cdkFocusInitial
입력에 효과가 있습니다.자세한 내용은 여기에서 확인할 수 있습니다. https://material.angular.io/cdk/a11y/overview
각도 템플릿만 사용
<input type="text" #searchText>
<span (click)="searchText.focus()">clear</span>
할 때는 오대이/화를상사때를 .cdkFocusInitial
에 내에cdkTrapFocus
그리고.cdkTrapFocusAutoCapture
.
CdkTrapFocus 디렉티브와 함께 cdkFocusInitial을 사용하는 경우 cdkTrapFocus를 활성화하지 않으면 아무 일도 일어나지 않습니다.AutoCapture 옵션도 있습니다.이는 CdkTrapFocus가 기본적으로 초기화에 대한 포커스를 캡처하지 않기 때문입니다.
오버레이/대화 상자 구성 요소:
<div cdkTrapFocus cdkTrapFocusAutoCapture>
<input cdkFocusInitial>
</div>
@john-white 제로셋 타임아웃으로 마법이 작동하는 이유는
this.searchElement.nativeElement.focus();
브라우저 callStack의 끝으로 전송되므로 마지막/나중에 실행됩니다. 이것은 그것을 작동시키는 아주 좋은 방법이 아니며 아마도 코드에 개선될 수 있는 다른 논리가 있다는 것을 의미합니다.
저는 블러 기능을 사용한 후에야 작동했습니다.
그것을 깨끗하게 유지하기 위해 나는 그것에 대한 지시를 내렸습니다.
import { Directive, ElementRef } from '@angular/core';
import { IonInput } from '@ionic/angular';
@Directive({
selector: '[appAutofocus]'
})
export class AutofocusDirective {
constructor(private el: ElementRef) {
}
async ngOnInit() {
const input = this.el.nativeElement as IonInput;
await input.setBlur();
await input.setFocus();
}
}
이것을 하는 것도 더 쉬운 방법입니다.
let elementReference = document.querySelector('<your css, #id selector>');
if (elementReference instanceof HTMLElement) {
elementReference.focus();
}
언급URL : https://stackoverflow.com/questions/50006888/set-focus-on-input-element
'programing' 카테고리의 다른 글
디렉토리에 폴더가 있는지 확인하고 C#을 사용하여 폴더를 만듭니다. (0) | 2023.05.17 |
---|---|
angular-cli 여기서 is webpack.config.js 파일 - new angular6은 ng 배출을 지원하지 않습니다. (0) | 2023.05.17 |
파이썬 3 바이트 문자열 변수를 일반 문자열로 변환하려면 어떻게 해야 합니까? (0) | 2023.05.17 |
iPad 및 iPhone용 스타일 입력 버튼 (0) | 2023.05.17 |
이미지 URI 소스 및 데이터 바인딩 (0) | 2023.05.17 |