Este equipo redactor ha pasado mucho tiempo buscando la solución a tus preguntas, te regalamos la solución por esto nuestro objetivo es que te sea de mucha ayuda.
Solución:
keypress
no detecta el arrow keys
en su lugar utiliza keydown
. Para recibir el foco y escuchar el key añadir eventos attribute tabindex
a los divs.
Para flecha derecha keydebe verificar si el elemento activo actual no es un último elemento y cambiar el enfoque al siguiente elemento.
Para flecha izquierda keyverifique si el elemento activo actual no es un primer elemento y luego cambie el enfoque al elemento anterior.
–HTML–
cell 2
cell 3
cell 4
cell 5
cell 6
cell 7
cell 8
–Código de componente–
length: 0;
domEles;
moveCell(e)
const activeEle = document.activeElement;
const activeEleIndex = Array.prototype.indexOf.call(this.domEles, activeEle);
if(e.key == "ArrowRight" && activeEleIndex < this.length - 1 )
activeEle.nextElementSibling.focus();
if(e.key == "ArrowLeft" && activeEleIndex > 0)
activeEle.previousElementSibling.focus();
ngOnInit()
this.domEles = document.querySelectorAll('.container > *');
this.length = this.domEles.length;
Working Code
– https://stackblitz.com/edit/angular-5qxicw.
Hay otro enfoque usando la directiva. Bueno, la idea es que obtengamos todo el div que tiene nuestra directiva en nuestro componente de aplicación usando ViewChildren, luego nuestro div con una directiva envíe un evento y llame a una función de nuestro componente de aplicación. Entonces la aplicación. componente se vuelve como
my div
my div
...
Pero podemos usar un “servicio” para hacer las cosas más “transparentes”.
Imagina un servicio como
@Injectable(
providedIn: 'root',
)
export class KeyBoardService
keyBoard:Subject=new Subject();
sendMessage(message:any)
this.keyBoard.next(message)
Nuestra directiva puede llamar al servicio “sendMessage” cuando un key Se presiona la flecha, y en nuestra app.component suscribirse a este servicio. y luego nuestro app.component es algo como
my div
my div
my div
my div
¡Evitamos este “feo” (evento)=”handler($event)” en nuestros divs!
Bueno, la directiva en simple, usando @Hostlistener para escuchar el keyy renderer2 para agregar el atributo “tabindex” (para hacer un div enfocable, necesitamos agregar tabIndex). Entonces
@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;
Y nuestro app.component.ts
export class AppComponent implements OnInit
columns:number=2;
@ViewChildren(ArrowDivDirective) inputs:QueryList
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
Vea que usé una variable "columna" si estamos haciendo una "cuadrícula" con columnas y filas y use arriba y abajo keys para moverse entre filas. Enviar el "elemento" para evitar que tengamos almacenado el "div enfocado"
Puedes ver un ejemplo en stackblitz
Reseñas y calificaciones
Tienes la posibilidad dar visibilidad a este enunciado si te ayudó.