web-dev-qa-db-fra.com

Utilisation d'un commutateur avec des chaînes en JavaScript

Mon instruction switch ne fonctionne pas correctement lors de l'analyse d'une variable de chaîne. 

La sortie et l'entrée sont toutes deux de <textarea>.

HTML

<form name="interface">
  <textarea name="output" rows="20" cols="100"></textarea><br>
  <textarea name="input" rows="1" cols="100" onKeyDown="thinkInput(event);"></textarea>
</form>

JavaScript

function thinkInput(e)
{
    if (e.keyCode == 13)
    {
        sInput = document.interface.input.value;
        document.interface.output.value += sInput;
        aInput = sInput.split(" ");

        switch (aInput[0])
        {
            case "say":
                textOut("You say \""+sInput.substring(aInput[0].length + 1)+"\"");
                break;
            case "move":
                move(aInput[1]);
                break;
            default:
                thinkFail();
                break;
        }
        document.interface.input.value = null;
        alert(aInput[0]);
    }
}

Je peux voir dans mon alert() à la fin que le cas est soit "dire" soit "déplacer". 

La première fois que j'essaye de "dire mudkipz" ou de "bouger", tout fonctionne comme je le veux, mais après tout ce que je tape, thinkFail() se déclenche.

14
MF Ramen

Votre code ne s'exécute pas car une nouvelle ligne apparaît au-dessus de la commande Invite et le tableau divisé ne contient pas la valeur de référence du premier mot sur [0]. Je ne sais pas pourquoi, même si vous effacez la valeur de l'entrée.

Comme vous n'aurez besoin que d'une ligne pour cette entrée, je vous suggère d'utiliser <input type="text" onKeyDown="thinkInput(event);"/> pour éviter d'avoir de nouvelles lignes en mode entrée.

JavaScript

this.thinkInput = function (e)
{   
    ...

    if (e.keyCode == 13)
    {   
        /* Prevent submitting form on Enter */ 
        e.preventDefault();

        var command, commands;

        command = cmd.value;
        commands = command.split(' ');
        /* Clear input field */
        cmd.value = '';

        /* commands[0] will always have reference
           to the first Word in textfield */
        switch (commands[0])
        {
            ...
        }
    }
}

Voici un petit violon que j'ai jeté ensemble à partir de votre code: http://jsfiddle.net/npx86/1/

J'espère que cela t'aides!

2
Matej Svajger

L'un des problèmes est que vous n'utilisez pas l'instruction var pour définir vos variables. Cela signifie qu'ils deviennent des "globaux implicites" et sont conservés via vos différents appels.

var sInput = document.interface.input.value;
var aInput = sInput.split(" ");
document.interface.output.value += sInput;

Pour diagnostiquer davantage le problème, vous pouvez utiliser les outils de débogage de votre navigateur pour insérer un point d'arrêt, puis consulter la valeur sInput et localiser le problème.

1
rbhro

Placez cette ligne avant le commutateur ....

aInput = sInput.split(" ");
aInput[0] = aInput[0].replace(/\s/gi, "");

switch (aInput[0])
{

....

Ou vous pouvez utiliser pour la saisie de texte, au lieu de textarea.

0
user3281733

Peut-être qu'il me manque quelque chose ... lorsque je regarde/teste ce code, il s'exécute chaque fois que l'événement keydown est déclenché et, comme vous effacez le champ de saisie, nous ne travaillons qu'avec des caractères uniques.

Si je devais taper "say", le code serait exécuté avec "s", puis "A", puis "y".

Si ce que vous voulez faire si vous analysez la zone de texte à la recherche de ces mots, je vous conseillerais d'extraire la valeur de document.interface.output.value et de comparer cette valeur à votre cas.

J'espère que cela t'aides.

EDIT: Pouvez-vous publier votre méthode de déplacement, votre méthode textOut et votre méthode thinkFail? D'après ce que je peux dire si une exception est frappée, c'est alors que l'affaire ne fonctionne pas. J'ai créé un jsfiddle où cela fonctionne bien.

0
Android334

Avez-vous essayé l'un de ces?

à la fin

document.interface.input.value = ""; 

Ce devrait vraiment être une chaîne vide, comme null + "bonjour"> "nullhello"

ou au début

document.interface.output.value = sInput; 

Est-il utile d'ajouter la chaîne si vous réinitialisez la valeur de sortie à chaque fois?

0
widged

Cela se produit parce que après réinitialisant la valeur de la boîte input à vide, la touche enfoncée (entrée) est ajoutée. Cela provoque aInput[0] pour commencer avec un CR (que vous ne verriez pas dans le message alert().

Vous pouvez facilement résoudre ce problème en coupant le côté gauche de sInput avant de le scinder:

aInput = sInput.replace(/^\s+/,'').split(" ");

Sinon, vous pouvez annuler l'événement keydown en renvoyant false explicitement à partir de la fonction lorsque vous avez appuyé sur <CR> et modifiez le code HTML en:

onkeydown="return thinkInput(event);"
0
Ja͢ck

Je sais que cela fait longtemps que cette question n’a pas été posée, mais je dois quand même donner une réponse.

La raison pour laquelle votre code ne fonctionne pas, c'est que l'entrée Textarea n'est pas vide après le premier essai. Le saut de ligne est toujours ajouté à la zone de texte une fois le code exécuté et la prochaine fois que vous appuyez sur entrée, c'est le premier caractère de l'entrée.

Si vous définissez onKeyDown sur onKeyUp ou ajoutez un nouveau gestionnaire d'événements pour onKeyUp afin de vider l'entrée, tout devrait bien se passer.

<textarea name="input" rows="3" cols="100" onKeyUp="thinkInput(event);"></textarea>

http://jsfiddle.net/borglinm/ntj3t/1/

0
Mathias