Веб-копирование и вставка в один клик

внешний интерфейс

В недавней веб-разработке я столкнулся с использованиемClipboardместо действия. То есть в веб-бизнесе на стороне B для конфигурации сложных страниц предполагается обеспечить复制粘贴Функция. Было рассмотрено несколько вариантов:

  • Опираясь на фоновый интерфейс, добавление данных С точки зрения спроса более простым решением являетсяПерезвоните интерфейс, чтобы создать новый., пользователь может изменить новые данные. Этот метод работает для той же среды (productилиdevnet) копировать вставить.

  • внешнее локальное хранилище,новыйОбнаружить во время работы инициируется пользователемкопироватьКогда поведение, хранить данные локальноlocalStorage, когда пользователь выполняетновыйПри работе обнаружитьlocalStorageЕсть ли реплицированные данные. Потому что это зарезервированный интерфейскопироватьданные, вы можете использоватьтестовая средаа такжеСетевое окружениекопировать-вставить между. Однако переключение между тестовой средой и реальной сетевой средой здесь зависит от конфигурации прокси. Для приложений, которые различают среды по разным доменным именам (например,xxx.xx.com or test.xxx.xx.com), localStorage ограничен политикой одного источника и не может считывать данные между доменами.

  • Использование буфера обмена На основе упомянутой выше схемы внешнего локального хранилища мы придумалиclipboardстроить планы. Подобно схеме Taobao, сохраните данные в буфер обмена, а затем определите буфер обмена при добавлении новых данных. Использование буфера обмена использует хранилище данных системы, а также решает междоменную проблему между разными доменными именами.

Запись в буфер обмена

document.execCommand

docment.execCommandявляется работоспособным可编辑内容区域изСинхронизироватьметод.

// 语法
bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument);

первый параметр методаaCommandNameвходящее командное слово, включаяcopy, cut, bold, backColorи так далее. Второй параметр методаaShowDefaultUIОтносится к тому, отображается ли пользовательский интерфейс, и этот параметр обычно не используется. Третий параметр методаaValueArgumentнекоторые дополнительные параметры при передаче команды действия. Метод возвращает логическое значение, описывающее успешность операции. Для получения подробной информации см.MDN

Что нам нужно сделать, так это записать необходимый контент в буфер обмена, о чем мы упоминали выше.copy

Без лишних слов давайте посмотрим, как использовать эту функцию через код

<div>
    <input type="text" value="Copy Content"/>
    <button onclick="handleClick">copy</button>
</div>
const i = document.querySelector('input');
// 获得焦点
i.select();
document.execCommand('copy');

нажмите кнопку,Copy ContentОн будет записан в буфер обмена, после чего вы сможете копировать и вставлять содержимое буфера обмена в другие места.

В этот момент всем будет любопытно: «Зачем использоватьinputЧто насчет компонентов? "Конечно, работаетtextareaэто тоже хорошо. упомянутый выше可编辑区域, Толькоinput, textareaили иметьcontenteditableАтрибутированные элементы могут быть толькоexecCommandдействовать

Тогда, если вы не хотите появляться на странице可编辑区域, что тогда можно сделать?

/**
 * @description 复制内容到剪切板
 * @param {string} content 文本内容
 */
function copy2Clipboard = content => {

  const dom = document.createElement('input');
  dom.value = content;
  document.body.appendChild(dom);
  dom.select();
  document.execCommand('copy');

  document.body.removeChild(dom);
};

Вы можете использовать вышеуказанный хитрый метод~

navigator.clipboard.writeText

вышесказанноеdocument.execCommandсинхронная операция,navigator.clipboardЭто API буфера обмена, предоставляемый браузером. Работа с буфером обмена может быть реализована через этот API, и в последнее время его поддерживают все основные производители браузеров.navigator.clipboardAPI.

浏览器兼容性

Итак, как его использовать?Мы все еще исходим из кода один за другим.

navigator.permissions.query({ name: 'clipboard-write' }).then(function(result) {
    // 可能是 'granted', 'denied' or 'prompt':
    if (result.state === 'granted') {
        // 可以使用权限
        // 进行clipboard的操作
        navigator.clipboard.writeText('Clip Content').then(
            function() {
                /* clipboard successfully set */
                // 成功设置了剪切板
            },
            function() {
                /* clipboard write failed */
                // 剪切板内容写入失败
            }
        );
    } else if (result.state === 'prompt') {
        // 弹窗弹框申请使用权限
    } else {
        // 如果被拒绝,请不要做任何操作。
    }
});

剪切板权限申请提示

navigator.permissionsЭто API, в котором браузер запрашивает у пользователя использование конфиденциального интерфейса, и вызывающий интерфейс выводит пользователю всплывающее окно с запросом, может ли пользователь использовать соответствующее разрешение. В приведенном выше коде первый запрос запроса используетclipboard-writeПрава на использование буфера обмена. После того, как разрешение будет передано, позвонитеnavigator.clipboard.writeTextметод.

navigator.clipboardAPI планируется заменитьdocument.execCommandинтерфейс, поэтому также рекомендуется использоватьclipboardAPI на ходу复制操作.

код показывает, как показано ниже:

async function copy2Clipboard(content) {
    const res = await navigator.permissions.query({ name: 'clipboard-write' });
    if (res.state === 'granted') {
        return navigator.clipboard.writeText(content);
    }

    return Promise.reject(res);
}

Обратите внимание на официальный аккаунт [сообщества IVWEB], чтобы еженедельно просматривать новейшие технологии и становиться лучше!


Чтение буфера обмена

document.execCommand

Учитывая соображения безопасности,document.execCommand('paste')Операция запрещена.

Итак, как я могу прочитать содержимое буфера обмена?

Слушайте событие вставки

document.addEventListener('paste', event => {
    // 从event中读取clipboardData
    const pasteContent = (event.clipboardData || window.clipboardData).getData('text');
    // do whatever
});

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

Так что еще есть?

navigator.clipboard.readText

navigator.clipboard.readTextЭто также операция буфера обмена API, предоставленная браузером, а такжеwriteTextТочно так же необходимо запросить разрешение буфера обмена.

// 申请使用剪切板读取权限
navigator.permissions.query({ name: 'clipboard-read' }).then(function(result) {
    // 可能是 'granted', 'denied' or 'prompt':
    if (result.state === 'granted') {
        // 可以使用权限
        // 进行clipboard的操作
        navigator.clipboard
            .readText()
            .then(text => {
                console.log('复制粘贴文本: ', text);
            })
            .catch(err => {
                // 读取剪切板内容失败
                console.error('Failed to read clipboard contents: ', err);
            });
    } else if (result.state === 'prompt') {
        // 弹窗弹框申请使用权限
    } else {
        // 如果被拒绝,请不要做任何操作。
    }
});

Сначала мы должны подать заявку на использование буфера обменаclipboard-readРазрешения, после получения прав пользователя можно пройтиnavigator.clipboard.readTextПолучать разрешение.

Мониторинг курсаpasteсобытия также возможны

document.addEventListener('paste', event => {
    event.preventDefault();
    navigator.clipboard.readText().then(text => {
        console.log('Pasted text: ', text);
    });
});

Поэтому мы можем абстрагироваться от функции чтения содержимого буфера обмена:

/**
 * @description 读取剪切板内容
 * @return {string}
 */
async function readClipboard() {
    const result = await navigator.permissions.query({ name: 'clipboard-read' });
    if (result.state === 'granted' || result.state === 'prompt') {
        return navigator.clipboard
            .readText()
            .then(text => text)
            .catch(err => Promise.reject(err));
    }
    return Promise.reject(result);
}

Резюме и заметка

Очистить содержимое буфера обмена

Браузеры не предоставляют интерфейс для очистки буфера обмена. Если веб-сайту необходимо очистить содержимое после использования содержимого буфера обмена, он может перезаписать данные.

// ...
input.value = ' '; // input的值必须有值, 不能是空字符串
input.select();
document.execCommand('copy')
// 或者使用clipboard
navigator.clipboard.writeText('');

безопасный вопрос

Веб-манипулирование содержимым буфера обмена сопряжено с определенными рисками безопасности. Для обеспечения конфиденциальности пользователя браузер требует использованияnavigator.clipboardAPI должен быть подключенHTTPS.

Веб-сайты HTTP не поддерживают этот интерфейс, поддерживаются толькоdocument.execCommand('copy')и слушаюpasteмероприятие

С точки зрения пользователя также рекомендуется, чтобы все веб-сайты имели доступ к HTTPS.

Будущее буфера обмена

Может поддерживать более общийwriteа такжеreadметод, обеспечивающий запись бинарных данных и т.п. (например, картинок и т.п.).

Ссылаться на

Unblocking Clipboard Access

Cut and Copy Commands