[英]How do I set the Button Element so that they can be controlled with arrow keys?
[英]How do i set arrow key focus on these button in angular while pressing the left and right arrow keys?
在这里,当我向左和向右按箭头键时,它没有聚焦,或者我无法使用箭头键导航或选择这些按钮,但是当调整这些键码的值时,它会根据按下的键打印,我需要知道如何获得按下箭头键时关注html,以便可以使用箭头键导航按钮,如果有人可以为我提供解决方案,那将是一个很大的帮助。
组件.html
<ng-template #content let-modal>
<div class="modal-header">
<h3 class="modal-title">Accept Offer</h3>
</div>
<div class="modal-body">
<p>Do you really want to accept the offer?</p>
</div>
<div class="modal-footer>
<button type="submit" class="btn btn-primary tab" (click)="onAcceptOffer()" arrow-div>Submit</button>
<button type="button" class="btn btn-secondary tab" (click)="modal.dismiss('Crossclick');
isClicked=false" arrow-div>Cancel</button></div>
</ng-template>
服务.ts
export class KeyBoardService {
keyBoard:Subject<any>=new Subject<any>();
sendMessage(message:any)
{
this.keyBoard.next(message)
}
}
指令.ts
@Directive({
selector: '[arrow-div]',
})
export class ArrowDivDirective {
constructor(private keyboardService: KeyBoardService, public element: ElementRef, private render: Renderer2) {
this.render.setAttribute(this.element.nativeElement, "tabindex", "0")
}
@HostListener('keydown', ['$event']) onKeyUp(e) {
switch (e.keyCode) {
case 38:
this.keyboardService.sendMessage({ element: this.element, action: 'UP' })
break;
case 37:
this.keyboardService.sendMessage({ element: this.element, action: 'LEFT' })
break;
case 40:
this.keyboardService.sendMessage({ element: this.element, action: 'DOWN' })
break;
case 39:
this.keyboardService.sendMessage({ element: this.element, action: 'RIGTH' })
break;
}
}
}
组件.ts
columns:number=2;
@ViewChildren(ArrowDivDirective) inputs:QueryList<ArrowDivDirective>
constructor(private keyboardService:KeyBoardService){}
ngOnInit()
{
this.keyboardService.keyBoard.subscribe(res=>{
this.move(res)
})
}
move(object)
{
const inputToArray=this.inputs.toArray()
let index=inputToArray.findIndex(x=>x.element==object.element);
switch (object.action)
{
case "UP":
index-=this.columns;
break;
case "DOWN":
index+=this.columns;
break;
case "LEFT":
index--;
break;
case "RIGTH":
index++;
break;
case "RIGTH":
index++;
break;
}
if (index>=0 && index<this.inputs.length)
{
inputToArray[index].element.nativeElement.focus();
}
}
我想代码来自这个SO
这种方法的“问题”是您应该先关注一个 HTML 元素,然后才能使用箭头键。
我们可以采取另一种方法:服务订阅 document.fromEvent('document')
想象一下像这样的服务
import {map,filter,tap} from 'rxjs/operators'
@Injectable({
providedIn: 'root',
})
export class KeyBoardService {
keyBoard:Subject<any>=new Subject<any>();
subscription:Subscription
sendMessage(message:any)
{
this.keyBoard.next(message)
}
init()
{
if (!this.subscription)
this.subscription=fromEvent(document,'keydown').pipe(
filter((e:Event)=>{
const el=document.activeElement
const ev=(e as KeyboardEvent)
//only want if the key is an arrow
const isArrow=ev.keyCode>=37 && ev.keyCode<=40
//and is the "body" or is arrow down and we are not
//in a select or is an "arrow-div"
return isArrow && (el.tagName== 'body' ||
(ev.keyCode==40 && el.tagName!='SELECT') ||
el.getAttribute('arrow-div')==='')
}),
map(e=>{
const obj={element:document.activeElement,action:null}
switch ((e as KeyboardEvent).keyCode) {
case 38:
obj.action='UP'
break;
case 37:
obj.action='LEFT'
break;
case 40:
obj.action='DOWN'
break;
case 39:
obj.action='RIGTH'
break;
}
return obj
})).subscribe(res=>{
this.sendMessage(res)
})
}
destroy()
{
this.subscription.unsubscribe()
this.subscription=null;
}
}
还有一个指令
@Directive({
selector: '[arrow-div]',
})
export class ArrowDivDirective {
element:HTMLElement
constructor(private keyboardService: KeyBoardService,
private el: ElementRef, private render: Renderer2) {
this.render.setAttribute(this.el.nativeElement, "tabindex", "0")
this.element=this.el.nativeElement;
}
}
看,在这种情况下我们不使用@HotListener,并且“元素”属性是HTMLElement(不是nativeElement)
我们可以在我们的组件中使用
@ViewChildren(ArrowDivDirective) inputs: QueryList<ArrowDivDirective>;
constructor(private keyboardService: KeyBoardService) {}
ngOnInit() {
this.keyboardService.init();
this.keyboardService.keyBoard.subscribe((res) => {
this.move(res);
});
}
move(object: any) {
const inputToArray = this.inputs.toArray();
let index = inputToArray.findIndex((x) => x.element == object.element);
if (index < 0) index = 0;
else {
switch (object.action) {
case 'UP':
index -= this.columns;
break;
case 'DOWN':
index += this.columns;
break;
case 'LEFT':
index--;
break;
case 'RIGTH':
index++;
break;
case 'RIGTH':
index++;
break;
}
}
if (index >= 0 && index < this.inputs.length) {
inputToArray[index].element.focus();
}
}
ngOnDestroy() {
this.keyboardService.destroy();
}
看到有必要“初始化”我们的服务(开始订阅 fromEvent(document,'keydown'),并在 ngOnDestroy 中删除订阅
新的堆栈闪电战
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.