2016-12-07 3 views
0

Quelle approche recommanderiez-vous pour contrôler l'application entière avec le clavier seulement? J'ai trouvé Spotlight lib, mais cela dépend de enyojs qui semble avoir son propre modèle de composant et enyojs global semble être une exagération.angular2: comment contrôler l'application entière avec le clavier seulement?

Jusqu'à présent, je suis à l'écoute des événements keydown dans app.component.ts:

@HostListener('window:keydown', ['$event']) onKeydown(event: any) { 
    event.preventDefault(); 
    this.mainKeydownHandler.handle(event.keyCode); 
} 

Chaque composant qui veulent gérer les événements keydown registres à MainKeydownHandler est gestionnaire et que l'événement keydown MainKeydownHandler délégués occures un événement au gestionnaire enregistré . Le gestionnaire approprié est déterminé par la classe de document.activeElement (je n'ai pas trouvé de méthode de type "angular2-like" pour obtenir la méthode actuellement ciblée) dans la méthode de gestion de MainKeydownHandler. Donc maintenant je dois ajouter le nom de classe approprié à un groupe d'éléments que je veux pouvoir mettre au point.

En outre, le gestionnaire de composants obtient tous les éléments sélectionnables avec:

@ViewChildren('selectable') elements: QueryList<ElementRef>; 

donc je dois ajouter #selectable et classe avec ID de gestionnaire à chaque élément que je veux me concentrer. Le gestionnaire du composant reçoit alors keyCode et détermine quel élément sélectionner ensuite ou retourner à l'élément précédemment sélectionné depuis un autre composant et ainsi de suite. Cette approche semble gênante, implique beaucoup de code quand un nouveau composant veut gérer les événements de keydown et il y a des situations où un composant perd complètement son focus: quand je supprime un élément d'une liste, puis ce composant est rendu (certains service ou MainKeydownHandler pourrait se souvenir, mais cela pourrait conduire à beaucoup d'éléments à retenir au cours de la navigation de l'utilisateur à travers les composants).

Existe-t-il un moyen plus simple, plus simple, plus générique et plus déclaratif de contrôler toute l'application angular2 à l'aide du clavier (événements keydown/keyup)?

Alternativement, est-il raisonnable d'utiliser Spotlight (avec enyojs dep.) Avec angular2 pour ce cas d'utilisation? Et pouvez-vous fournir plunker de travail avec spotlight angulaire2 +. Je ne pouvais pas faire fonctionner ces deux-là ensemble.

+0

Voulez-vous naviguer autour des éléments avec clavier ou ont des actions personnalisées en réponse à des événements de clavier comme dans un jeu? – sabithpocker

+0

juste la navigation (haut, bas, droite, gauche) et sélectionnez (entrée) –

Répondre

0

Si vous souhaitez activer la navigation au clavier de base, vous pouvez le faire avec tabindex, ce qui est une manière standard de le faire. Voir la specification

document.getElementById('mylist').focus();
:focus{ 
 
    border: 1px solid red; 
 
    }
Press TAB to navigate. 
 
<ul id="mylist" tabindex="-1"> 
 
    <li tabindex="1"> One </li> 
 
    <li tabindex="2"> Two </li> 
 
    <li tabindex="4"> Four </li> 
 
    <li tabindex="3"> Three </li> 
 
</ul>

Si vous voulez faire avec les touches fléchées, vous devrez écouter événement keydown sur le document et manuellement focus() les éléments en utilisant javascript. Il sera plus facile de naviguer d'avant en arrière, pas directement pour trouver l'élément qui est au-dessus et en dessous de l'élément actuel dans la mise en page. Vous devrez comparer les coordonnées x, y ou les décalages.

document.getElementById('mylist').focus(); 
 

 
window.onkeydown = function(e) { 
 
    var curr = document.activeElement; 
 
    var treeWalker = document.createTreeWalker(
 
    document.body, 
 
    NodeFilter.SHOW_ELEMENT, 
 
    { acceptNode: function(node) { return (node.tabIndex === -1)?NodeFilter.FILTER_SKIP: NodeFilter.FILTER_ACCEPT} }, 
 
    false 
 
); 
 
    treeWalker.currentNode = curr; 
 
    
 
    if (e.keyCode == 39) { 
 
    treeWalker.nextNode().focus(); 
 
    } 
 
    if (e.keyCode == 37) { 
 
    treeWalker.previousNode().focus(); 
 
    } 
 
};
:focus { 
 
    border: 1px solid red; 
 
}
Press Right/Left arrow keys to navigate 
 
<ul id="mylist" tabindex="-1"> 
 
    <li tabindex="1">One</li> 
 
    <li tabindex="2">Two</li> 
 
    <li tabindex="4">Four</li> 
 
    <li tabindex="3">Three</li> 
 
    <li>Not selectable</li> 
 
    <li tabindex="5">Five</li> 
 
</ul>

1

Vous pouvez jeter un oeil à https://github.com/luke-chang/js-spatial-navigation Il est une bibliothèque de navigation spatiale générique. Il devrait pouvoir être intégré facilement avec Angular.

Vous pouvez également consulter ce lié SO: Navigate the UI using only keyboard

Et cette application angulaire TV qui prétend avoir une navigation spatiale: https://github.com/ahmednuaman/angular-tv-app

+0

J'essayais de créer une application TV en utilisant angulaire 4 mais incapable d'utiliser 'js-spacial-navigation'. des pensées sur la façon de l'utiliser? – Santosh