# Изменение: change, input, propertychange На элементах формы происходят события клавиатуры и мыши, но есть и несколько других, особенных событий. ## Событие change Событие [change](http://www.w3.org/TR/html5/forms.html#event-input-change) происходит по окончании изменении значения элемента формы, когда это изменение зафиксировано. Для текстовых элементов это означает, что событие произойдёт не при каждом вводе, а при потере фокуса. Например, пока вы набираете что-то в текстовом поле ниже -- события нет. Но как только вы уведёте фокус на другой элемент, например, нажмёте кнопку -- произойдет событие `onchange`. ```html ``` Для остальных же элементов: `select`, `input type=checkbox/radio` оно срабатывает сразу при выборе значения. [warn header="Поздний `onchange` в IE8-"] В IE8- `checkbox/radio` при изменении мышью не инициируют событие сразу, а ждут потери фокуса. Для того, чтобы видеть изменения `checkbox/radio` тут же -- в IE8- нужно повесить обработчик на событие `click` (оно произойдет и при изменении значения с клавиатуры) или воспользоваться событием `propertychange`, описанным далее. [/warn] ## Событие propertychange Это событие происходит только в старых IE, до версии 11, при любом изменении свойства. Оно позволяет отлавливать изменение тут же и используется, преимущественно, для исправления ошибок в старых IE. Если поставить его на `checkbox` в IE8-, то получится "правильное" событие `change`: ```html Чекбокс с "onchange", работающим везде одинаково ``` Это событие также срабатывает при изменении значения текстового элемента, но в IE9 у него ошибка: оно не срабатывает при удалении символов. ## Событие input Событие `input` срабатывает *тут же* при изменении значения текстового элемента и поддерживается всеми браузерами, кроме IE8-. В IE9 оно поддерживается частично, а именно -- *не возникает при удалении символов* (как и `onpropertychange`). Пример использования (не работает в IE8-): ```html oninput: ``` ## События cut, copy, paste Эти события используются редко. Они происходят при вырезании/вставке/копировании значения. К сожалению, кросс-браузерного способа получить данные, которые вставляются/копируются, не существует, поэтому их основное применение -- это отмена соответствующей операции. Например, вот так: ```html event: ``` ## Пример: поле с контролем СМС Как видим, событий несколько и они взаимно дополняют друг друга. Посмотрим, как их использовать, на примере. Сделаем поле для СМС, рядом с которым должно показываться число символов, обновляющееся при каждом изменении поля. Как такое реализовать? Событие `input` идеально решит задачу во всех браузерах, кроме IE9-. Собственно, если IE9- нам не нужен, то на этом можно и остановиться. ### IE9- В IE8- событие `input` не поддерживается, но, как мы видели ранее, есть `onpropertychange`, которое может заменить его. Что же касается IE9 -- там поддерживаются и `input` и `onpropertychange`, но они оба не работают при удалении символов. Поэтому мы будем отслеживать удаление при помощи `keyup` на [key Delete] и [key BackSpace] . А вот удаление командой "вырезать" из меню -- сможет отловить лишь `oncut`. Получается вот такая комбинация: ```html символов: ``` Здесь мы добавили вызов `showCount` на все события, которые могут приводить к изменению значения. Да, иногда изменение будет обрабатываться несколько раз, но зато с гарантией. А лишние вызовы легко убрать, например, при помощи `throttle`-декоратора, описанного в задаче [](/task/throttle). **Есть и совсем другой простой, но действенный вариант: через `setInterval` регулярно проверять значение и, если оно слишком длинное, обрезать его.** Чтобы сэкономить ресурсы браузера, мы можем начинать отслеживание по `onfocus`, а прекращать -- по `onblur`, вот так: ```html символов: ``` Обратим внимание -- весь этот "танец с бубном" нужен только для поддержки IE8-, в которых не поддерживается `oninput` и IE9, где `oninput` не работает при удалении. ## Итого События изменения данных:
Событие | Описание | Особенности |
---|---|---|
`change` | Изменение значения любого элемента формы. Для текстовых элементов срабатывает при потере фокуса. | В IE8- на чекбоксах ждет потери фокуса, поэтому для мгновенной реакции ставят также `onclick`-обработчик или `onpropertychange`. |
`input` | Событие срабатывает только на текстовых элементах. Оно не ждет потери фокуса, в отличие от `change`. | В IE8- не поддерживается, в IE9 не работает при удалении символов. |
`propertychange` | Только для IE10-. Универсальное событие для отслеживания изменения свойств элементов. Имя изменённого свойства содержится в `event.propertyName`. Используют для мгновенной реакции на изменение значения в старых IE. | В IE9 не срабатывает при удалении символов. |
`cut/copy/paste` | Срабатывают при вставке/копировании/удалении текста. В них можно отменить действие браузера, и тогда вставке/копирования/удаления не произойдёт. | Вставляемое значение получить нельзя: на момент срабатывания события в элементе всё ещё *старое* значение, а новое недоступно. |