7
votes

JS arrowdown AddeventListener pour plusieurs éléments en boucle (démo)

avoir suivant l'auditeur pour clavier arrowdown code> événement (Code de clé est 40 code>):

window.onload = function() {    
var itemsContainer = document.getElementById('cities-drop');
document.addEventListener('keyup',function(event){
if (event.keyCode == 40 && itemsContainer.style.display=='block') {
event.preventDefault();
    for (var i=0;i<itemsContainer.children.length-1;i++){
        if (itemsContainer.getAttribute('class').substr('hovered')!=-1){
            itemsContainer.children[i].setAttribute('class','');
            itemsContainer.children[i].nextSibling.setAttribute('class','hovered');
                //break;
                }
            }
        }
    });


6 commentaires

Qu'essayez-vous d'atteindre? Un menu déroulant personnalisé?


@ Šime vidas vous avez absolument raison


Pourquoi essayez-vous de l'écrire vous-même? Il existe des bibliothèques et des cadres offrant cette fonctionnalité.


@ Šime Vidas Je sais. C'est la tâche dans mon plan d'apprentissage JS.Je dis davantage - je l'ai écrit dans pure JS.


Qu'essayez-vous d'atteindre? Voulez-vous sélectionner un élément dans cette liste avec les touches arrow_up et arrow_down?


Šime Vidas Oui, pour naviguer sur la liste avec le clavier arrow_up et arrow_down clés


3 Réponses :


4
votes

Après avoir regardé votre code et réalisez ce que vous essayez de faire, je pense que votre erreur utilise substr code> où vous devez utiliser indexof code>. Voici la ligne mise à jour:

<html>
<head>
    <style type="text/css">
        .hovered
        {
            color:red;
        }
    </style>
    <script type="text/JavaScript">
        function move(event)
        {
            var itemsContainer = document.getElementById('cities-drop');
            if (event.keyCode == 40 && itemsContainer.style.display == 'block')
            {
                if (event.preventDefault)
                    event.preventDefault();
                if (event.cancelBubble)
                    event.cancelBubble();
                if (event.stopImmediatePropagation)
                    event.stopImmediatePropagation();

                for (var i=0; i<itemsContainer.children.length-1; i++)
                {
                    if (itemsContainer.children[i].className.indexOf('hovered') != -1)
                    {
                        itemsContainer.children[i].className = "";
                        itemsContainer.children[i+1].className = "hovered";
                        break;
                    }
                }
            }
        };
    </script>
</head>
<body onkeydown="move(event)">
    <div id="cities-drop" style="display:block;">
        <p class="hovered">Item 1</p>
        <p>Item 2</p>
        <p>Item 3</p>
        <p>Item 4</p>
        <p>Item 5</p>
        <p>Item 6</p>
        <p>Item 7</p>
    </div>
</body>
</html>


8 commentaires

Oui, c'est ma faute mannequin, j'ai utilisé substr non corrichement.anyway Cela n'a pas aidé-moi, ni indexof () , ni correspondant () , Javascript.info/play/pnq9e


Désolé pour la réponse tardive.Il fonctionne pour moi dans cette édition, que vous avez écrit ici. À partir d'autre côté, je n'ai pas besoin d'observateurs en ligne onkeydown = Move (événement) , alors quand j'essaie avec Addeventlistener , je te donnerai


@Severgionni: Veuillez garder à l'esprit que AddeventListener n'est pas pris en charge dans IE, qui est toujours l'un des navigateurs les plus courants utilisés. Vous obtiendrez une erreur JavaScript de objet ne prend pas en charge cette propriété ou cette méthode dans Internet Explorer. Si vous devez utiliser cette méthode, vous devez effectuer un chèque pour voir si la fonction existe d'abord. Voir Stackoverflow.com/a/1695383 pour un exemple.


Oui, je sais sur attachentEvent et AddeventListener .it n'est pas un problème. Le problème principal est que j'ai besoin d'auditeurs du tout, au lieu de "observateurs en ligne".


@Sergionni: Je suis confus quant à ce que vous entendez par "Observateur en ligne" ... Joindre un événement utilisant la méthode inline exécutera toujours la fonction de la même manière que l'utilisation de AddeventListener . La seule différence que je connaisse est que si vous essayez d'ajouter une autre action au même événement avec la méthode inline, l'action précédente sera écrasée, tandis que avec AddeventListener , les deux actions seront exécutées. La méthode inline est donc toujours un auditeur d'événement, le même.


Je veux dire, que je ne veux pas utiliser de construction telle que onkeywwed = "Move (événement)" dans mon HTML. addEventListener est plus flexible


@sergionni: assez juste. Voulez-vous accepter la réponse avant l'expiration de la générosité? Je peux toujours aider à discuter ou à quelque chose si vous avez besoin d'aide supplémentaire au-delà de cela. Merci.


Salut, parlons plus tard dans la discussion.anyway, vous répondez est le plus proche))))



3
votes

Il y a quelques choses que je peux voir que cela pourrait être un problème. Tout d'abord, vous mettez à jour itemsContainer.children [i] .nextsibling code> qui est itemontainer.children [i + 1] code>. C'est pourquoi toujours le dernier élément qu'il a sélectionné si vous ignorez la pause. Les articlesComtainer [i + 1] seront toujours planifiés s'il y aura sur l'article correspondant à la classe.

Le deuxième problème est ce que Travestern3 souligne dans sa réponse. P>

J'ai également changé la condition si La classe planée est sur l'un des enfants et non le conteneur lui-même. p> xxx pré>

J'ai modifié le gestionnaire d'événements avec les lignes de code suivantes, et cela semble fonctionner bien : P>

document.addEventListener('keyup',function(event){
            if (event.keyCode === 40 && itemsContainer.style.display==='block') {
                event.preventDefault();
                for (var i=0,l=itemsContainer.children.length;i<l;++i){
                    if (itemsContainer.children[i].getAttribute('class').match('hovered')){
                        itemsContainer.children[i].setAttribute('class','');
                        itemsContainer.children[i+1].setAttribute('class','hovered');
                        break;
                    }
                }
            }
        });


1 commentaires

Il semble que vous ayez oublié de mettre à jour la déclaration IF: Si (itemontainer.children [i] .getatTtribute ("classe"). Match ("hov éred")) {



3
votes

Vous pouvez essayer une approche plus simple au lieu d'utiliser une boucle: xxx


0 commentaires