Skip to content

Commit c7b668a

Browse files
authored
feat: update events-change-input article.md ru
1 parent 670ccab commit c7b668a

File tree

1 file changed

+32
-11
lines changed
  • 2-ui/4-forms-controls/3-events-change-input

1 file changed

+32
-11
lines changed

2-ui/4-forms-controls/3-events-change-input/article.md

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
```smart header="Нельзя ничего предотвратить в `oninput`"
5151
Событие `input` происходит после изменения значения.
5252

53-
Поэтому мы не можем использовать `event.preventDefault()` там - будет уже слишком поздно, никакого эффекта не будет.
53+
Поэтому мы не можем использовать `event.preventDefault()` там -- уже слишком поздно, никакого эффекта не будет.
5454
```
5555
5656
## События: cut, copy, paste
@@ -61,25 +61,46 @@
6161
6262
Мы также можем использовать `event.preventDefault()` для предотвращения действия по умолчанию, и в итоге ничего не скопируется/не вставится.
6363
64-
Например, код, приведённый ниже, предотвращает все подобные события и показывает, что мы пытаемся вырезать/копировать/вставить:
64+
Например, код, приведённый ниже, предотвращает все `cut/copy/paste` события и показывает текст, который мы пытаемся вырезать/копировать/вставить:
6565
6666
```html autorun height=40 run
6767
<input type="text" id="input">
6868
<script>
69-
input.oncut = input.oncopy = input.onpaste = function(event) {
70-
alert(event.type + ' - ' + event.clipboardData.getData('text/plain'));
71-
return false;
69+
input.onpaste = function(event) {
70+
alert("paste: " + event.clipboardData.getData('text/plain'));
71+
event.preventDefault();
72+
};
73+
74+
input.oncut = input.oncopy = function(event) {
75+
alert(event.type + '-' + document.getSelection());
76+
event.preventDefault();
7277
};
7378
</script>
7479
```
7580

76-
Технически, мы можем скопировать/вставить всё. Например, мы можем скопировать файл из файловой системы и вставить его.
81+
Обратите внимание: внутри обработчиков событий `cut` и `copy` вызов `event.clipboardData.getData(...)` возвращает пустую строку. Это потому, что технически данные ещё не находятся в буфере обмена. Если мы используем `event.preventDefault()` они вообще не будут скопированы.
82+
83+
Поэтому в приведённом выше примере используется `document.getSelection()` для получения выделенного текста. Более подробную информацию о выделении в документе можно найти в главе <info:selection-range>.
84+
85+
Возможно копирование/вставка не только текста, но и любых данных. Например, мы можем скопировать файл в файловом менеджере ОС и вставить его.
86+
87+
Это потому, что `clipboardData` реализует интерфейс `DataTransfer`, обычно используемый для перетаскивания и копирования/вставки. Сейчас это немного выходит за рамки нашего рассмотрения, но вы можете найти его методы в [спецификации DataTransfer](https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface).
88+
89+
Кроме того, существует дополнительный асинхронный API для доступа к буферу обмена: `navigator.clipboard`. Подробнее -- в спецификации [Clipboard API and events](https://www.w3.org/TR/clipboard-apis/), [не поддерживается в Firefox](https://caniuse.com/async-clipboard).
90+
91+
## Ограничения безопасности
92+
93+
Буфер обмена работает глобально, на уровне ОС. Пользователь может переключаться между приложениями, копировать/вставлять различные данные, и страница браузера не должна всё это видеть.
94+
95+
Поэтому большинство браузеров разрешают беспрепятственный доступ к буферу обмена для чтения/записи только в рамках определённых действий пользователя, таких как копирование/вставка и т.д.
96+
97+
Запрещено генерировать "пользовательские" события буфера обмена с помощью `dispatchEvent` во всех браузерах, кроме Firefox. И даже если нам удастся создать такое событие, спецификация чётко указывает, что такие "синтетические" события не должны предоставлять доступ к буферу обмена.
7798

78-
Существует список методов [в спецификации](https://www.w3.org/TR/clipboard-apis/#dfn-datatransfer) для работы с различными типами данных, чтения/записи в буфер обмена.
99+
Даже если кто-то решит сохранить `event.clipboardData` в обработчике событий, а затем обратиться к нему позже -- это не сработает.
79100

80-
Но обратите внимание, что буфер обмена работает глобально, на уровне ОС. Большинство браузеров в целях безопасности разрешают доступ на чтение/запись в буфер обмена только в рамках определённых действий пользователя, к примеру, в обработчиках событий `onclick`.
101+
Повторим: [event.clipboardData](https://www.w3.org/TR/clipboard-apis/#clipboardevent-clipboarddata) работает исключительно в контексте обработчиков событий, инициированных пользователем.
81102

82-
Также запрещается генерировать "пользовательские" события буфера обмена при помощи `dispatchEvent` во всех браузерах, кроме Firefox.
103+
С другой стороны, [navigator.clipboard](https://www.w3.org/TR/clipboard-apis/#h-navigator-clipboard) -- более современный API, предназначенный для использования в любых сценариях. Он запрашивает разрешение пользователя, если это необходимо.
83104

84105
## Итого
85106

@@ -88,5 +109,5 @@
88109
| Событие | Описание | Особенности |
89110
|---------|----------|-------------|
90111
| `change`| Значение было изменено. | Для текстовых полей срабатывает при потере фокуса. |
91-
| `input` | Срабатывает при каждом изменении значения. | Запускается немедленно, в отличие от `change`. |
92-
| `cut/copy/paste` | Действия по вырезанию/копированию/вставке. | Действие можно предотвратить. Свойство `event.clipboardData` предоставляет доступ на чтение/запись в буфер обмена.. |
112+
| `input` | Для текстовых полей при каждом изменении значения. | Запускается немедленно, в отличие от `change`. |
113+
| `cut/copy/paste` | Действия по вырезанию/копированию/вставке. | Действие можно предотвратить. Свойство `event.clipboardData` предоставляет доступ на чтение/запись в буфер обмена. Все браузеры, кроме Firefox, также поддерживают `navigator.clipboard`. |

0 commit comments

Comments
 (0)