Копировать текст в буфер обмена при нажатии действия браузера расширения Chrome - PullRequest
1 голос
/ 22 февраля 2020

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

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

Boilerplate

manifest. json:

{
    "name": "Example",
    "version": "0.0.0",
    "manifest_version": 2,
    "permissions": ["clipboardWrite"],
    "browser_action": {"default_title": "Copy some text"},
    "background": {
        "scripts": ["events.js"],
        "persistent": false
    }
}

events. js:

chrome.browserAction.onClicked.addListener(_ => {
    copy(new Date().toISOString().slice(0, 19))
})

// Define copy() here.

Подход 1

Не определяйте copy и надеюсь, что он определен глобально, как в консоли.

Это не так.

Подход 2

function copy(text) {
    navigator.clipboard.writeText(text)
}

Это не происходит с сообщением об ошибке «DOMException: документ не сфокусирован».

Подход 3

function copy(text) {
    focus()
    navigator.clipboard.writeText(text)
}

Это ведет себя так же, как подход 2 .

Подход 4

function copy(text) {
    const ta = document.createElement('textarea')
    ta.value = text
    ta.select()
    document.execCommand('copy')
    ta.remove()
}

Сбой без сообщения об ошибке.

Подход 5

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

Подход 6

function copy(text) {
    open('copy.html?' + encodeURIComponent(text), '', 'width=1,height=1')
}

(Настройка ширины и высоты заставляет открывать окно, а не вкладку, чтобы сохранить выбор вкладки пользователя и уменьшить визуальный эффект.)

copy. html:

<!doctype html>
<meta charset="utf-8">
<title>Copying…</title>
<div></div>
<script src="copy.js"></script>

copy. js:

(async _ => {
    await navigator.clipboard.writeText(decodeURIComponent(location.search.slice(1)))
    close()
})()

Это работает, но не очень хорошо, потому что визуально глючно, медленно и круто.

1 Ответ

2 голосов
/ 22 февраля 2020

Элемент textarea должен быть сначала добавлен к действующему DOM, например, к document.body и сфокусирован, потому что execCommand работает на document.activeElement. Вы можете скрыть текстовое поле, чтобы оно не мерцало.

function copy(text) {
  const ta = document.createElement('textarea');
  ta.style.cssText = 'opacity:0; position:fixed; width:1px; height:1px; top:0; left:0;';
  ta.value = text;
  document.body.appendChild(ta);
  ta.focus();
  ta.select();
  document.execCommand('copy');
  ta.remove();
}

Возможно, вам понадобится установить еще несколько CSS пропусков на none или 0, таких как border / padding / margin, на всякий случай.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...