Использование переключателя со строками в JavaScript

Оператор My switch работает неправильно при анализе строковой переменной.

Выход и вход являются как <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]);
    }
}

В моем alert() я вижу в конце, что случай либо "говорит", либо "перемещается".

В первый раз, когда я пытаюсь "сказать mudkipz" или "перемещаться", все работает так, как я хочу, но после этого все, что я набираю, thinkFail() срабатывает.

Ответы

Ответ 1

Одна из проблем заключается в том, что вы не используете оператор var для определения своих переменных. Это означает, что они становятся "неявными глобальными" и сохраняются через ваши разные вызовы.

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

Чтобы дополнительно диагностировать проблему, вы можете использовать инструменты отладчика в своем браузере, чтобы вставить точку останова, и выполнить шаг, чтобы контролировать значение sInput и найти проблему.

Ответ 2

Ваш код не выполняется из-за новой строки, которая появляется над командной строкой, а разделительный массив не содержит ссылочное первое слово по значению [0]. Не знаю, почему, хотя вы очищаете значение ввода.

Поскольку вам понадобится только одна строка на этом входе, я предлагаю использовать <input type="text" onKeyDown="thinkInput(event);"/>, чтобы избежать ввода новых строк.

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])
        {
            ...
        }
    }
}

Вот небольшая скрипка, которую я выбросил из вашего кода: http://jsfiddle.net/npx86/1/

Надеюсь, это поможет!

Ответ 3

Это происходит потому, что после сброса значения поля input в значение "пусто" добавляется нажатая клавиша (ввод). Это приводит к тому, что aInput[0] начинается с CR (который вы не увидите в сообщении alert().

Вы можете легко исправить это, обрезая левую сторону sInput, прежде чем разделить его:

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

В качестве альтернативы вы можете отменить событие keydown, возвращая false явно из функции при нажатии <CR> и изменив HTML на:

onkeydown="return thinkInput(event);"

Ответ 4

Попробовали ли вы это?

в конце

document.interface.input.value = ""; 

Это действительно должна быть пустая строка, так как null + "hello" > "nullhello"

или в начале

document.interface.output.value = sInput; 

Действительно ли он служит цели для добавления строки, если вы reset выходное значение каждый раз?

Ответ 5

Возможно, мне что-то не хватает... когда я ищу/проверяю этот код, он запускается каждый раз, когда запускается событие keydown, и поскольку вы очищаете поле ввода, мы работаем только с одиночными символами.

Если бы я набрал "say", тогда код выполнил бы с "s", затем "a", затем "y".

Если вы хотите сделать это, сканируя текстовое поле для этих слов, я бы рекомендовал потянуть значение document.interface.output.value и сравнить это значение с вашим случаем.

Надеюсь, что это поможет.

EDIT: Можете ли вы опубликовать свой метод перемещения, метод textOut и метод thinkFail? Из того, что я могу сказать, попало ли какое-либо исключение, тогда дело не будет работать. Я создал jsfiddle, где он отлично работает.

Ответ 6

Поместите эту строку перед коммутатором ....

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

switch (aInput[0])
{

....

Или вы можете использовать для ввода текста вместо текстового поля.

Ответ 7

Я знаю, что прошло какое-то время, так как это было задано, но я должен предоставить ответ в любом случае.

Причина, по которой ваш код не работает, заключается в том, что входной Textarea не является пустым после первой попытки. Linebreak по-прежнему добавляется в текстовое поле после запуска кода, и в следующий раз, когда вы нажмете enter, это первый char на входе.

Если вы либо измените onKeyDown на onKeyUp, либо добавите новый eventHandler для onKeyUp, чтобы очистить ввод, вы должны быть в порядке.

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

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