Сводка операций копирования и вставки буфера обмена

внешний интерфейс Безопасность JavaScript Chrome

буфер обмена

В ежедневной разработке интерфейса операции, связанные с буфером обмена, относительно невелики. Но для некоторых конкретных сценариев он будет использоваться просто необходимо. Например: для разработки расширенного текстового редактора нажмите ctrl + v, загрузите изображения, заплатите (типичное использование - игра в плохие детские игры), красное сокровище, пароль автоматически копируется.

операция с буфером обмена

событие буфера обмена

Самый простой способ работы с буфером обмена — прослушивание событий буфера обмена. Из соображений совместимости обычно доступ к clipboardData осуществляется только в функции обработчика событий буфера обмена, а данные чтения браузера, отличного от IE, могут использоваться только в событии onpaste. Чтобы использовать события буфера обмена для чтения и записи данных, пользователь должен активно использовать сочетания клавиш или контекстное меню. Таким образом, основным сценарием применения события платы мониторинга является перехват данных после того, как пользователь инициирует их.

document.execCommand

Метод document.execCommand() используется для управления содержимым редактируемой области. Например, наиболее часто используемая команда «копировать» может копировать содержимое области выделения в буфер обмена. С помощью метода window.getSelection(), вы можете автоматически выбрать область содержимого и записать содержимое в буфер обмена. Библиотека clipboard.js и автоматическое копирование паролей в красных конвертах в основном достигаются с помощью этого метода.

Есть также некоторые проблемы с этим методом:

  • Chrome\Safari не поддерживает команду «вставить»
  • Chrome не может напрямую вызывать команду «копировать» в фоновом режиме, она должна запускаться щелчком пользователя.
  • IE может напрямую вызвать и щелкнуть, чтобы вызвать команду «копировать» в фоновом режиме, но будет запрос на разрешение

Asynchronous Clipboard API

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

Только представьте, что происходит, когда вы просматриваете веб-страницы, нажимаете страницу или кнопку и копируете пароль красного пакета Alipay? эээ, все еще приемлемо? Так'rm -rf /'Шерстяная ткань? (Я использую Windows, чего я боюсь?)

API асинхронного буфера обмена и API разрешений буфера обмена, которые являются новыми дополнениями к API буфера обмена, предназначены для решения вышеупомянутых проблем и устранения различных поворотов и рисков безопасности. На данный момент (2018.03) в Chrome 66 реализованы некоторые функции, и прогнозируется, что в будущем будут изменения, в этой статье мы не будем их подробно описывать. Кратко характеристики сводятся к следующему:

  • Можно вызывать только по HTTPS
  • Страница находится в активной вкладке для вызова
  • На основе промисов для простых асинхронных операций и обработки ошибок
  • Реализована программная вставка (чтение) и копирование (запись)
  • Разрешения на вставку (чтение) и копирование (запись) добавлены в API разрешений, операции требуют авторизации пользователя.
  • В настоящее время API разрешений буфера обмена работает только с API асинхронного буфера обмена. Будет добавлен во все API буфера обмена в будущем в соответствии со спецификацией.

Паста для обработки (Paste)

Для вставки в настоящее время широко поддерживаются только сочетания клавиш и триггеры контекстного меню, а программных сценариев использования, поддерживаемых IE, не так много, поэтому я не буду их здесь представлять.

Обычный текст или форматированный текст

Блокировка простого текста

El.addEventListener('paste', event => {
    event.preventDefault();
    let clipboardData = event.clipboardData || window.clipboardData, // IE 兼容
        plainText = clipboardData.getData('text');  // 无格式文本
    
    // ... 对 plainText 进行一系列处理操作
    
    document.execCommand('insertText', false, plainText);  // 插入无格式文本
    document.execCommand('paste', false, plainText);  // IE 兼容
})

Для дальнейшей обработки форматированного текста можно использовать следующие методы, чтобы преобразовать его в DOM-структуру, а затем оперировать. (Браузер IE не может получить 'text/html', поэтому он не может реализовать следующие функции)

    /* 仍在上述事件处理函数中,下面均省略 */
    let plainHTML = clipboardData.getData('text/html'),   // 有格式文本
        domContainer = document.createElement('div');
    domContainer.innerHTML = plainHTML;
    
    // ... 对 domContainer 进行一系列处理操作
    
    El.innerHTML = domContainer.innerHTML; // 使用 innerHTML 方式整体插入
    El.appendChild(nodeOfDomContainer); // 只插入其中某个节点

картина

Если в структуре DOM есть тег изображения, рассмотрите возможность загрузки изображения на сервер, а затем замените его src адресом, возвращенным сервером.

Если копия представляет собой одно изображение (например, скопированное из Word), вы можете использовать следующий метод, чтобы получить DataURL изображения, а затем загрузить его. (Браузер IE автоматически создаст тег изображения с DataURL при вставке изображения, поэтому следующий метод не требуется)

    let items = clipboardData.items;
    for (let i = 0; i < items.length; i++) {
        let item = items[i];
        if (/image/.test(item.type)) {
            let file = item.getAsFile(), // 得到文件对象
                reader = new FileReader();
            reader.onload = function() {
                upload(reader.result) // 上传图片,伪代码
            }
            reader.readAsDataURL(file); // 读取为 DataURL / Base64
        }
    }

обрабатывать копию ( копировать )

Горячая клавиша и триггер контекстного меню

Обычный сценарий приложения — перехватить операцию копирования, обработать скопированный контент и затем записать его в буфер обмена, например добавить информацию об авторских правах после копирования большого фрагмента текста в Zhihu.

El.addEventListener('copy', event => {
    event.preventDefault();
    let clipboardData = event.clipboardData || window.clipboardData,
        text = window.getSelection().toString();
    
    // ... 对 text 进行一系列处理操作
    
    clipboardData.setData('text/plain', text); // 将处理好的 text 写入剪贴板
    clipboardData.setData('text', text); // IE 兼容
})

программная репликация

Хотя это программная копия, она не может быть полностью автоматической, и пользователю необходимо сначала инициировать событие щелчка. Библиотека clipboard.js и автоматическое копирование пароля красного конверта (прослушивание события щелчка в документе) в основном достигаются с помощью этого метода.

Фиксированный контент

Button.addEventListener('click', event => {
    let sometext = '红包码 xxxxxx',
        hiddenInput = document.createElement('input');
    hiddenInput.value = sometext;
    hiddenInput.setAttribute('readonly', '');
    hiddenInput.style.position = 'absolute';
    hiddenInput.style.left = '-9999px';
    document.body.appendChild(hiddenInput);
    hiddenInput.select();
    hiddenInput.setSelectionRange(0, hiddenInput.value.length); // ios
    document.execCommand('copy');
    document.body.removeChild(hiddenInput);
})

Скопируйте текст внутри элемента

Button.addEventListener('click', event => {
    let someElement = document.getElementById('someelement'),
        selection = window.getSelection(),
        range = document.createRange();
    range.selectNodeContents(element);
    selection.removeAllRanges();
    selection.addRange(range);
    document.execCommand('copy');
})

Можно обнаружить, что текущая работа буфера обмена действительно странная, надеюсь новый API скоро станет реальностью (мечтать)!

Ссылаться на

[1] Clipboard API and events | w3c

[2] clipboard.js | Github

[3] Реализация редактора форматированного текста с помощью javascript | Nuggets

[4] Предварительное знакомство с редактором форматированного текста | Nuggets

[5] JavaScript копирует содержимое в буфер обмена | Самородки