keyPress event

13th January 2005 - 00:55

В последнее время тема JS очень греет, потому что я не знаю этого языка. Точнее, знаю некоторые основы и пару-тройку глюков браузеров. Сижу, ковыряю. Одно из самых приятных чувств — это когда после долгих ковыряний, обхода багов и мата, код начинает работать. В CSS порой то же самое творится; родные братья.

Небольшая задачка.

Конкретизируем: на странице есть две textarea, работая в одной из которых мы должны иметь возможность пользоваться сочетаниями Ctrl+B и Ctrl+U для каких-то своих целей, например задания bold/underline выделенного в этой textarea фрагмента текста, а другую оставим нетронутой, т.е. там эти сочетания клавиш будут вызывать «родные» действия браузера (в Mozilla это работа с закладками и просмотр исходного кода страницы).

HTML:

<form>
    <textarea id="enabledTextArea">
        CTRL+B || CTRL+U
    </textarea>
    <textarea>
        !(CTRL+B || CTRL+U)
    </textarea>
</form>

Лирическое отступление: при помощи quirksmode.org и хорошего мануала под рукой решается большинство задач. Меньшинство не решается, да. Но это уже проблемы браузеров.

Посмотрим как подобное можно осуществить в Опере. Стоп. Это как раз из разряда «проблемы». Полноценного WYSIWYG не получится. Ну хоть попробуем отловить нажатия интересующих нас комбинации в надежде на то, что норвежцы когда-нибудь прислушаются к пользователям и кодерам:

Javascript:

function keyAction(e)
{
    if (!enabled || e.shiftKey || e.altKey || !e.ctrlKey) return;
    var text;
    switch (e.keyCode)
    {
        case 66:
            text = "|Ctrl+B|";
            break;
        case 85:
            text = "|Ctrl+U|";
            break;
        //case else:
    }
    if (text)
    {
        textarea.value += text;
        e.preventDefault();
    }
}

function keyPressInit()
{
    textarea = document.getElementById("enabledTextArea");
    if (!textarea) return;
    textarea.onfocus = function(){enabled=true;}
    textarea.onblur = function(){enabled=false;}
    document.onkeypress = function(e){keyAction(e);}
}

var textarea, enabled;
window.onload = keyPressInit;

Коротко о логике: при загрузке окна вызываем функцию keyPressInit для нахождения элемента с нужным нам id. Если такой элемент есть на странице, то вешаем на него обработчик нажатия клавиш и потери/приобретения фокуса.

Теперь по нажатию на клавиши в бой идёт функция keyAction, в которую передаём событие (e). Нам необходимо «чистое» сочетание Ctrl+Key, поэтому, если были нажаты Alt, Shift, не было нажатия на Ctrl или нет фокуса на texarea, то завершаем работу функции; в противном случае смотрим цифровое значение нажатой клавиши (e.keyCode) и, в зависимости от этого значения, работаем с переменной text. Если на выходе из switch эта переменная не осталась пустой, то добавляем её к textarea и прерываем обработку события. Если же переменная пуста, то событие продолжается (это необходимо, если мы хотим оставить пользователям возможность работы с Ctrl+X|C|V и другими сочетаниями).

Я взял лишь один браузер, потому как в этом случае код получается простым и понятным. Если перевести это всё на рельсы трёх браузеров, то будем иметь приблизительно следующее:

Javascript:

function keyAction(e)
{
    if (!enabled || e.shiftKey || e.altKey || !e.ctrlKey) return;
    var Key = e.keyCode;
    if (Key == 0) Key = e.charCode;
    if (!gecko && Key>64 && Key<91) Key += 32;
    var text;
    switch (Key)
    {
        case 98:
            text = "|Ctrl+B|";
            break;
        case 117:
            text = "|Ctrl+U|";
            break;
        //case else:
    }
    if (text)
    {
        textarea.value += text;
        e.preventDefault ?
            e.preventDefault() :
            e.returnValue = false;
    }
}

function keyPressInit()
{
    textarea = document.getElementById("enabledTextArea");
    if (!textarea) return;
    textarea.onfocus = function(){enabled=true;}
    textarea.onblur = function(){enabled=false;}

    if (document.addEventListener)
    {
        document.addEventListener("keypress",
                function(e){keyAction(e)},true);
        if (window.opera) return;
        document.addEventListener("keydown",
                function(e){keyAction(e)},true);
        gecko = true;
    }
    else if (document.attachEvent)
        document.attachEvent("onkeydown", keyAction);
}

var textarea, enabled, gecko;
window.onload = keyPressInit;

И я балдею от этих «маленьких» отличий. После того, как начнёт работать, конечно. А порой руки опускаются и начинаешь крыть матом «лебедя, рака и щуку».

PS: все баги мои, все достоинства найдены путём подсматривания в WikiEdit.

Categories: dHtml | comments: (5)

Комментарии

1. Slach 13th January 2005 - 16:02

еще раз огромное спасибо за помощь
сам бы наверное долго доходил

при адаптации под мои нужды выяснилось что для Mozilla Opera достаточно переопределить document.onkeypress

и сотавить в покое document.onkeydown =)

2. redux 14th January 2005 - 05:18

что, бля, не ждали, а я пришел :))))))))

3. Вадим 14th January 2005 - 05:57

Вовик, сайт специфический…На узкоспециализированные вещи. Я ничего не понимаю, но кучу:) администратору создаю. Но лично я рад тебя вновь услышать. Скажи где «обитаешь», я зайду, и как в старое доброе время — СПЛЯШЕМ НА СТОЛЕ :)))) p.s. только не на феминистическом сайте:))))))))))))))) p.p.s. а чё не спишь…

4. redux 18th January 2005 - 23:33

не сплю потому что режим такой Ж))))))))

5. Вадим 19th January 2005 - 19:58

худеешь? (очень громкий смех)

Комментарии временно отключены.