JavaScript: полезные события

Владимир | | JavaScript, Web разработка.

Недавно мне нужно было написать обычный счетчик символов в текстовой области (textarea). Задача тривиальная, но меня заинтересовал один нюанс.

Вопрос в том, какое событие обрабатывать?

Пользователь может вводить текст как угодно, с помощью клавиатуры, вставлять из буфера обмена.
Если ввод происходит с помощью клавиатуры или из буфера комбинацией клавиш Ctrl+V, то можно обрабатывать событие onKeyup. Но если текст вставлен с помощью контекстного меню, то onKeyup не работает (действительно, ведь клавиатуру мы не трогаем). Точно также не имеет смысла обрабатывать события мыши. Ведь клик выполняется по контекстному меню, а обработчик мы назначаем для textarea.

Событие onChange тоже не подходит, т.к. оно появляется после того как textarea теряет фокус.

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

Но я решил поискать. И прежде всего, отправился поэкспериментировать с формой twitter’а. Первый же эксперимент дал положительный результат. Вставка через контекстное меню изменила значение счетчика.

Сначала я подумал, что они решают задачу с помощью таймера и проверок длины поля через заданный интервал времени. Но потом я заметил, что эта функция работает только в FireFox и не работает в IE.

А чем отличается Firefox от IE? Конечно, поддержкой новых стандартов!

После этого я быстро нашел нужное событие. Оно называется input и определено в спецификации DOM Level 3 Load And Save.
Это событие возникает сразу после ввода любых символов в поле не зависимо от способа ввода.

Чтобы не оставаться голословным я привожу страницу, с которой экспериментировал.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
    <title>textArea</title>

    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <meta http-equiv="Content-Style-Type" content="text/css" />

</head>

<body>

<div><textarea id="messageText" cols="45" rows="15"></textarea></div> <div>Количество символов: <span id="symbolsCounter"></span></div> <script type="text/javascript" src="jquery-1.3.1.min.js"></script> <script type="text/javascript"> $(function() { var ta = $("#messageText"); var counter = $("#symbolsCounter"); counter.html(ta.val().length); if ($.browser.mozilla && $.browser.version.substr(0,3)=="1.9") { ta.bind("input", function() { updateCounter(); }); } else { ta.bind("keyup", function() { updateCounter(); }); } function updateCounter() { counter.html(ta.val().length); var split = ta.val().split("\n"); if (split.length > 15) { ta.attr("rows", split.length); } } }); </script> </body> </html>

На странице размещены текстовая область (строка 16) и блок для вывода количества символов (строка 18).

Наибольший интерес представляет JS код. Посмотрим, как он работает.

Прежде всего, проверяем какой браузер используется. Если это FireFox последних версий, назначаем для текстовой области обработчик события input (строки 26-29), если нет – будем обрабатывать keyup (строки 31-34).

При возникновении этих событий вызывается функция updateCounter, в которой мы определяем и показываем количество символов в текстовой области (строка 38).

Остальной код в функции updateCounter испольлзуется для изменения высоты текстовой области, если введенный текст превышает её размер. Алгоритм тут простой.

Разбиваем текст с помощью функции split на лексемы (строка 39), а в качестве разделителя используем символ конца строки. В результате получаем массив с количеством элементов равным количеству строк. Если это количество превысит дефолтное значение (15) – изменяем размер текстовой области (строки 40-42).

Как видите, в новых стандартах есть интересные и, самое главное, полезные нововведения.

Жаль, что разработчики браузеров от них сильно отстают.

Интересно почитать

Реклама в блогах от студии SMOpro —
наиболее эффективный способ продвижения вашего ресурса.