Коды ключей JavaScript

Я работаю с подпрограммой JavaScript, которую не писал. Он вызывается из атрибута onkeydown текстового поля для предотвращения нежелательных нажатий клавиш.

Первый аргумент, по-видимому, не используется. Второй аргумент — это список разрешенных символов.

function RestrictChars(evt, chars) {
    var key;
    var keychar;

    if (window.event)
        key = window.event.keyCode;
    else if (e)
        key = e.which;
    else
        return true;

    keychar = String.fromCharCode(key);

    if ((key == null) || (key == 0) || (key == 8) ||
        (key == 9) || (key == 13) || (key == 27))
        // Control key
        return true;
    else if (((chars).indexOf(keychar) > -1))
        return true;
    else
        return false;
}

Кажется, это работает для буквенно-цифровых символов. Однако такие символы, как . и /, заставляют эту функцию возвращать false, даже если эти символы включены в параметр chars. Например, если нажата клавиша ., key устанавливается на 190, а keychar устанавливается на символ «3/4».

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


person Jonathan Wood    schedule 24.06.2011    source источник
comment
Эта утилита для проверки кодов клавиш может оказаться полезной для выяснения того, какие события возвращают какие коды клавиш для различных клавиш: west-wind.com/WestwindWebToolkit/samples/Ajax/html5andCss3/   -  person Rick Strahl    schedule 14.12.2011


Ответы (2)


Две вещи здесь неверны: во-первых, если вы анализируете, какой символ был набран, вам нужно использовать событие keypress вместо keydown, потому что это единственное событие, которое сообщает вам что-то надежное о фактическом набранном символе. Более подробную информацию об этом и ключевых событиях JavaScript в целом см. на http://unixpapa.com/js/key.html. Во-вторых, есть ссылки на переменную с именем e, которая не соответствует (но должна) соответствовать параметру evt.

Вот переписывание, предполагающее, что у вас есть переменная с именем textBox, которая ссылается на элемент ввода текста.

jsFiddle: http://jsfiddle.net/9DZwL/

Код:

function isKeypressCharValid(e, chars) {
    e = e || window.event;

    // Allow delete, tab, enter and escape keys through
    if (/^(8|9|13|27)$/.test("" + e.keyCode)) {
        return true;
    }

    var charCode = (typeof e.which == "number") ? e.which : e.keyCode;
    var charTyped = String.fromCharCode(charCode);
    return chars.indexOf(charTyped) > -1;
}

textBox.onkeypress = function(evt) {
    if (!isKeypressCharValid(evt, "abc123")) {
        return false;
    }
};
person Tim Down    schedule 24.06.2011
comment
Спасибо. Кажется, это работает. Я прочитаю об этом, но, возможно, вы могли бы ответить на пару быстрых вопросов. 1) Почему это не предотвращает использование управляющих символов, таких как backspace? 2) Какого черта || делает? (С моим фоном || является логическим ИЛИ, но здесь это не имеет смысла.) - person Jonathan Wood; 25.06.2011
comment
@Jonathan: я только что добавил немного, чтобы иметь дело с управляющими символами. || в JavaScript возвращает первый операнд, если он правдив (т. е. приводит к логическому true), и второй операнд в противном случае, поэтому его можно использовать как ярлык в условном присваивании. - person Tim Down; 25.06.2011
comment
@pst: ключевые события JavaScript — беспорядок. Я предлагаю прочитать страницу, на которую есть ссылка в моем ответе (значительно превосходящую страницу quirksmode, IMO), или мое более короткое резюме здесь: stackoverflow.com/questions/4285627/, а затем посмотрите, считаете ли вы, что мой ответ неверен. - person Tim Down; 25.06.2011
comment
@Ken: я указал две причины, по которым это не работает: во-первых, это неправильное событие, а во-вторых, неправильная переменная. По общему признанию, я не стал подробно рассказывать о том, что пытается сделать код, но предоставил ссылку на ресурс, который очень подробно объясняет, как именно работают ключевые события JavaScript. - person Tim Down; 25.06.2011
comment
@Jonathah Wood: || действительно логическое ИЛИ. Код в первой ветке if сообщает, равен ли ключ нулю ИЛИ равен ли ключ 0 или. Что касается вашего вопроса о возврате, он является частью этого теста с key == 8 (который является возвратом; 9 - табуляция, 13 - ввод (или возврат), а 27 - escape. - person Ken White; 25.06.2011
comment
@Ken: В целом я не согласен, но я думаю, что мой ответ мог бы быть более ясным, поэтому я немного изменил его и немного расширил. Считаете ли вы это разумным ответом сейчас? - person Tim Down; 25.06.2011
comment
@Tim: Намного лучше, ИМО. +1 от меня. - person Ken White; 25.06.2011
comment
@Ken: в C, C++ и C++ логическое ИЛИ всегда разрешается в логическое значение. Здесь он преобразуется в нелогическое значение. Так что в этом отношении все по-другому. Обратите внимание, что исходный код Тима не проверял наличие управляющих символов, и все же код, казалось, допускал их, поэтому мой вопрос. - person Jonathan Wood; 25.06.2011
comment
@Jonathan: это разрешается в логическое значение - true, если ключ соответствует одному из условий проверки, false, если нет. Это цепной тест - см. мой ответ. - person Ken White; 25.06.2011
comment
@Ken: я говорю о первой строке кода @Tim. Я понимаю операторы ИЛИ в вашем коде. - person Jonathan Wood; 25.06.2011
comment
@Jonathan: я дал довольно краткое объяснение использования || в комментарии выше. Документация Mozilla содержит более подробную информацию: developer.mozilla.org/en/JavaScript /Справочник/Операторы/ - person Tim Down; 25.06.2011
comment
@Jonathan: Извините, я думал, вы имели в виду || в исходном коде. - person Ken White; 25.06.2011
comment
@Tim: Спасибо за обновленный код; однако ваш исходный код (без кода, который проверяет наличие управляющих символов), по-видимому, правильно разрешает управляющие символы. Это меня смутило. Как будто onkeypress() выполняется только для печатных символов. Но я нигде не мог найти это документально. - person Jonathan Wood; 25.06.2011
comment
@Jonathan: Событие keypress в первую очередь предназначено для обнаружения нажатий клавиш, которые создают печатные символы, и все основные браузеры поддерживают его для этого. Однако некоторые браузеры запускают события keypress и для непечатаемых ключей, и это поведение сильно различается. unixpapa.com/js/key.html содержит много подробностей по этому поводу. - person Tim Down; 25.06.2011
comment
@pst: Ваше смелое заявление о том, что вы считаете мой ответ неверным, меня беспокоит. Я уверен, что вы ошибаетесь, и ваш комментарий громко подрывает авторитет моего ответа, делая его менее полезным для людей, которые придут к нему в будущем. - person Tim Down; 19.07.2011
comment
@Tim Down Достаточно честно. Я не должен был выделять это жирным шрифтом. - person ; 21.07.2011

Я тоже не специалист по JS, но... я могу объяснить, как это должно работать; Однако я не знаю, почему вы получаете значения для ключей, которые вы упомянули.

keychar = String.fromCharCode(key);

Это проверяет, является ли ключ печатным символом (буквой, знаком препинания и т.

if ((key == null) || (key == 0) || (key == 8) ||
    (key == 9) || (key == 13) || (key == 27))
    // Control key

Вышеприведенное проверяет, является ли ключ нулевым ИЛИ (||)` 0 или 8 (возврат), или 9 (табуляция), или 13 (0x0D, или ENTER), или 27 (0x1B или ESCAPE) - это точно логический результат, который вы бы ожидать: ЕСЛИ ‹это условие› или ‹то условие› или ‹другое условие› или ...

else if (((chars).indexOf(keychar) > -1))

Это проверяет, находится ли keychar в строке символов, переданной в качестве параметра chars.

person Ken White    schedule 25.06.2011