- Событие
change - Событие
propertychange - Событие
input - События
cut,copy,paste - Пример: поле для СМС
- Итого
На элементах формы происходят события клавиатуры и мыши, но есть и несколько других, особенных событий.
Событие change
Событие change происходит при изменении значения элемента формы. По стандарту, оно должно происходить после того, как элемент теряет фокус.
В реальности оно так и происходит для текстовых элементов.
Например, пока вы набираете что-то в текстовом поле ниже — события нет. Но как только вы уведёте фокус на другой элемент, например, нажмёте кнопку — произойдет событие onchange.
<input type="text" onchange="alert(this.value)"> <input type="button" value="Кнопка">
Для остальных же элементов: select, input type=checkbox/radio наблюдается кросс-браузерный зоопарк. Браузеры стараются генерировать событие при выборе значения, еще до потери фокуса элементом.
change на input type=checkbox/radio- Элементы
checkbox/radioпри изменении мышью инициируют событие тут же везде, кроме IE<9.
В IE<9 они ждут потери фокуса. - Элемент
selectтакже генерирует событие тут же при выборе значения везде, кроме Opera и IE<9.
В Opera/IE<9 они также генерируются при переборе значений с клавиатуры клавишами вверх-вниз.
Вы можете увидеть это самостоятельно в примере ниже:
<select onchange="alert(this.value)"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <input type="checkbox" onchange="alert(this.checked)"> <input type="button" value="Кнопка">
Выводы:
- Для того, чтобы видеть изменение
checkbox/radioтут же — в IE<9 нужно повесить обработчик на событиеclick(оно произойдет и при изменении значения с клавиатуры) или воспользоваться событиемpropertychange, описанным ниже. - С
selectобычно ничего такого не делают. В Opera/IE<9 будет работать немного по-другому при использовании клавиатуры для выбора.
Событие propertychange
Это событие происходит только в IE, при любом изменении свойства. Оно позволяет отлавливать изменение тут же.
Если поставить его на checkbox в IE<9, то получится «правильное» событие change:
<input type="checkbox"> Чекбокс с "onchange", работающим везде одинаково
<script>
var checkbox = document.body.children[0];
if("onpropertychange" in checkbox) {
// если поддерживается (IE)
checkbox.onpropertychange = function() {
if (*!*event.propertyName*/!* == "checked") { // имя свойства
alert(checkbox.checked);
}
};
} else {
// остальные браузеры
checkbox.onchange = function() {
alert(checkbox.checked);
};
}
</script>
Это событие также срабатывает при изменении значения текстового элемента, но по каким-то причинам, известным лишь в Индии - кроме удаления символов.
Попробуйте набрать что-то в текстовом поле, а затем удалить. При удалении значение в span не будет обновляться.
Пример — только для IE:
<input type="text"> onpropertychange: <span id="result"></span>
<script>
var input = document.body.children[0];
input.onpropertychange = function() {
if (event.propertyName == "value") {
document.getElementById('result').innerHTML = input.value;
}
}
</script>
В браузерах, за исключением IE<9 и Safari/Chrome, существует аналогичное событие DOMAttrModified, а также ряд других событий на изменение и добавление узлов.
Они описаны в стандарте Mutation Events. Но эта часть стандарта реализована в браузерах частично, с многочисленными ошибками, и объявлена устаревшей.
На практике такие события нужны, в основном, при отладке. А современные отладчики (Chrome/Safari, Firefox) позволяют вставить точку останова при изменении DOM и без этих событий.
Событие input
Событие input срабатывает тут же при изменении значения текстового элемента и поддерживается всеми браузерами, кроме IE<9.
В IE9 оно поддерживается частично, а именно — не возникает при удалении символов.
Пример использования (не работает в IE<9):
<input type="text"> oninput: <span id="result"></span>
<script>
var input = document.body.children[0];
input.oninput = function() {
document.getElementById('result').innerHTML = input.value;
}
</script>
События cut, copy, paste
Эти события используются редко, но иногда бывают полезны. Они происходят при вырезании/вставке/копировании значения в поле.
При этом действие браузера можно отменить, как это сделано в примере ниже:
<input type="text"> event: <span id="result"></span>
<script>
var input = document.body.children[0];
input.oncut = input.oncopy = input.onpaste = function(e) {
e = e || event;
document.getElementById('result').innerHTML = e.type +' '+input.value;
return false;
}
</script>
Эти события не дают доступ к данным, которые вставляются.
Также существуют события beforecut/beforecopy/beforepaste. Они интересны тем, что return false из beforecut/beforepaste позволяет включить вырезание/вставку для нередактируемых элементов. В дальнейшем эти действия можно будет обработать в событиях cut/paste
К сожалению, они нормально работают только в IE.
<div onbeforecut="return false" onbeforepaste="return false"> Для этого DIV включены команды меню Вырезать/Вставить (IE) </div>
Пример: поле для СМС
Сделаем поле для СМС, рядом с которым должно показываться число символов, обновляющееся при каждом изменении поля.
Как такое реализовать?
Событие input придумано специально для таких случаев. И оно идеально решает задачу во всех браузерах, кроме IE.
Но в IE<9 это событие не поддерживается, а в IE9 не работает при удалении. Что делать?
Вместо input для IE можно использовать propertychange, но оно не работает при удалении символов.
Впрочем, это не так страшно. Удаление нажатием Delete/BackSpace замечательно поймает keyup. А вот удаление командой «вырезать» из меню — сможет лишь отловить oncut.
Получается вот такая комбинация:
<input type="text"> символов: <span id="result"></span>
<script>
var input = document.body.children[0];
function showCount() {
document.getElementById('result').innerHTML = input.value.length;
}
input.oncut = input.onkeyup = input.oninput = showCount;
input.onpropertychange = function() {
if (event.propertyName == "value") showCount();
}
</script>
Теперь всё отлично, только вот событие cut срабатывает до вырезания, поэтому значение поля в нём еще не обновлено. В результате при вырезании мышью в IE количество символов не изменится. Как исправить этот маленький недостаток, мы увидим далее, при рассмотрении трюка setTimeout(.., 0).
Итого
События изменения данных:
| Событие | Описание | Особенности |
|---|---|---|
change |
Изменение значения любого элемента формы. Для текстовых элементов срабатывает при потере фокуса.
Для |
Для Opera/IE<9 срабатывает при переборе значений select с клавиатуры.
Для IE<9 на чекбоксах ждёт потери фокуса. |
input |
Событие срабатывает только на текстовых элементах. Оно не ждет потери фокуса в отличие от change. |
В IE<9 не поддерживается, в IE9 не работает при удалении. |
propertychange |
Только для IE. Универсальное событие для отслеживания изменения свойств элементов. Имя изменённого свойства содержится в event.propertyName.
Аналог в других браузерах, кроме Safari/Chrome — DOMAttrModified. |
Не срабатывает при удалении символов из текстового поля. |
cut/copy/paste |
Срабатывают при вставке/копировании/удалении текста. В них отменить действие браузера. | Вставляемое значение получить нельзя. На момент срабатывания события в элементе всё ещё старое значение. |
Для того, чтобы на чекбоксах в IE<9 отлавливать изменение тут же — можно повесить обработчик на click или использовать событие propertychange в дополнение к change.
В IE<9 события change(и аналогичные) не всплывают.
Можно увидеть это на следующем примере:
<form oninput="log(event)" onchange="log(event)" onpropertychange="log(event)" oncut="log(event)">
<input type="text"> <span id="log"></span>
</form>
<script>
function log(event) {
document.getElementById('log').innerHTML += ' '+event.type;
}
</script>
Для всех браузеров, кроме IE<9 события будут ловиться на FORM и отображаться справа от INPUT.
Создайте интерфейс для автоматического вычисления процентов по вкладу.
Ставка фиксирована: 12% годовых. При включённом поле «капитализация» — проценты приплюсовываются к сумме вклада каждый месяц (сложный процент).
Пример:
Технические требования:
- В поле с суммой должно быть нельзя ввести не-цифру. При этом пусть в нём работают специальные клавиши и сочетания Ctrl-X/Ctrl-V.
- Изменения в форме отражаются в результатах сразу.
Исходный документ: tutorial/form/percent-src.html.
Алгоритм решения такой.
Только численный ввод в поле с суммой разрешаем, повесив обработчик на keypress.
Отслеживаем события изменения для перевычисления результатов:
- На
input: событиеinputи дополнительноpropertychange/keyupдля совместимости со старыми IE. - На
checkbox: событиеclickвместоchangeдля совместимости с IE<9. - На
select: событиеchange.
Решение: tutorial/form/percent.html.
Комментарии
- Приветствуются комментарии, содержащие дополнения и вопросы по статье, и ответы на них.
- Если ваш комментарий касается задачи -- откройте её в отдельном окне и напишите там.
- Комментарии без смысла, с рекламой или не о статье вообще - удаляются.