Давайте розглянемо події, які супроводжують оновлення даних.
Подія: change
Подія change
спрацьовує після закінчення зміни елемента.
Для текстового поля це означає, що подія відбувається, коли втрачається фокус.
Наприклад, поки ми вводимо текст у текстовому полі нижче, події немає. Але коли ми перемістимо фокус кудись в інше місце, наприклад, натиснемо кнопку – відбудеться подія change
:
<input type="text" onchange="alert(this.value)">
<input type="button" value="Button">
Для інших елементів: select
, input type=checkbox/radio
подія запускається відразу після зміни значення:
<select onchange="alert(this.value)">
<option value="">Виберіть щось</option>
<option value="1">Варіант 1</option>
<option value="2">Варіант 2</option>
<option value="3">Варіант 3</option>
</select>
Подія: input
Подія input
запускається щоразу після того, як користувач змінює значення.
На відміну від подій клавіатури, input
запускається при будь-якій зміні значень, навіть тих, які не передбачають дії клавіатури: вставлення тексту за допомогою миші або використання розпізнавання мовлення для диктування тексту.
Наприклад:
<input type="text" id="input"> oninput: <span id="result"></span>
<script>
input.oninput = function() {
result.innerHTML = input.value;
};
</script>
Якщо ми хочемо обробляти кожну модифікацію <input>
, тоді ця подія є найкращим вибором.
З іншого боку, подія input
не запускається під час введення з клавіатури та інших дій, які не передбачають зміну значення, напр. натискання клавіш зі стрілками ⇦ ⇨.
oninput
Подія input
відбувається після зміни значення.
Тож ми не можемо використовувати там event.preventDefault()
– просто надто пізно, ефекту не буде.
Події: cut, copy, paste
Ці події відбуваються під час вирізання/копіювання/вставлення значення.
Вони належать до класу ClipboardEvent і надають доступ до даних, які вирізаються/копіюються/вставляються.
Ми можемо використовувати event.preventDefault()
, щоб припинити дію, тоді нічого не буде скопійовано/вставлено.
Наприклад, наведений нижче код запобігає всім подіям cut/copy/paste
і показує текст, який ми намагаємося вирізати/скопіювати/вставити:
<input type="text" id="input">
<script>
input.onpaste = function(event) {
alert("Вставити: " + event.clipboardData.getData('text/plain'));
event.preventDefault();
};
input.oncut = input.oncopy = function(event) {
alert(event.type + '-' + document.getSelection());
event.preventDefault();
};
</script>
Зверніть увагу: всередині обробників подій cut
та copy
виклик event.clipboardData.getData(...)
повертає порожній рядок. Це тому, що технічно даних ще немає в буфері обміну. Якщо ми використовуємо event.preventDefault()
, текст взагалі не буде скопійований.
Тож у прикладі вище використовується document.getSelection()
, щоб отримати виділений текст. Детальніше про вибір документів можна знайти в статті Selection і Range.
Можна копіювати/вставляти не тільки текст, а й все інше. Наприклад, ми можемо скопіювати файл у файловий менеджер ОС і вставити його.
Це тому, що clipboardData
реалізує інтерфейс DataTransfer
, який зазвичай використовується для перетягування та копіювання/вставлення. Зараз це трохи виходить за рамки наших можливостей, але ви можете знайти його методи в специфікації DataTransfer.
Крім того, існує додатковий асинхронний API для доступу до буфера обміну: navigator.clipboard
. Детальніше про це в специфікації Clipboard API та події, не підтримується в Firefox.
Обмеження у сфері безпеки
Буфер обміну – це “глобальна” річ на рівні ОС. Користувач може перемикатися між різними програмами, копіювати/вставляти різні речі, і сторінка браузера не повинна бачити всього цього.
Тому більшість браузерів надають безперешкодний доступ для читання/запису до буфера обміну лише в рамках певних дій користувача, таких як копіювання/вставлення тощо.
Заборонено генерувати “користувацькі” події буфера обміну з dispatchEvent
у всіх браузерах, крім Firefox. І навіть якщо нам вдасться відправити таку подію, у специфікації чітко зазначено, що такі “синтетичні” події не повинні надавати доступ до буфера обміну.
Навіть якщо хтось вирішить зберегти event.clipboardData
в обробник подій, а потім отримати до нього доступ пізніше – це не спрацює.
Ще раз, event.clipboardData працює виключно в контексті ініційованих користувачем обробників подій.
З іншого боку, navigator.clipboard – це найновіший API, призначений для використання в будь-якому контексті. Він запитує дозвіл користувача, якщо потрібно.
Підсумки
Події зміни даних::
Подія | Опис | Особливості |
---|---|---|
change |
Значення було змінено. | Для текстових полей спрацьовує при втраті фокусу. |
input |
Спрацьовує при кожній зміні значення. | Спрацьовує негайно, на відміну від change . |
cut/copy/paste |
Дії при вирізанні/копіюванні/вставлянні. | Дії можна запобігти. Властивість event.clipboardData надає доступ до буфера обміну. Усі браузери, крім Firefox, також підтримують navigator.clipboard . |
Коментарі
<code>
, для кількох рядків – обгорніть їх тегом<pre>
, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)