JavaScriptでクリップボードへコピー


はじめに

タイトルとURLが取れたので、次はクリップボードにコピーします。

クリップボードへコピー

調べてみると clipboardへのコピーは document でするみたいですね。

どうやって documentにコピーしたいデータを追加するかなぁと調べたら、そのものの例 Copying text to clipboard with JavaScript – Hacker Noon が見つかりました。document.createElement() ですね。

ポイント

  • documet.createElemet で要素にしてからコピー
  • position=absolute, left=-9999px で左の見えない場所に配置
  • document.getSelection().rangeCount でHTML中を選択してた場合も考慮

JavaScriptに慣れてないせいか、const と var の違いが把握できてないので今度調べてみます。

background.js
browser.contextMenus.create({
    id: "copyUrlForQiita",
    title: "copy url for qiita",
    contexts: ["all"]
});

browser.contextMenus.onClicked.addListener((info, tab) => {
   if (info.menuItemId === "copyUrlForQiita") {
        var urlForQiita = "[" + tab.title + "](" + tab.url + ")"
        copyToClipboard(urlForQiita);
    }
});

function copyToClipboard(str) {
    const el = document.createElement('textarea');
    el.value = str;
    el.setAttribute('readonly', '');
    el.style.position = 'absolute';
    el.style.left = '-9999px';
    document.body.appendChild(el);
    const selected = document.getSelection().rangeCount > 0 ? document
            .getSelection().getRangeAt(0) : false;
    el.select();
    document.execCommand('copy');
    document.body.removeChild(el);
    if (selected) { 
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(selected);
    }
};

Permissions

上のコードだけだと問題なかったのですが、いろいろ試している間に、

console
document.execCommand(‘cut’/‘copy’) はユーザー生成の短期的なイベントハンドラーの内部からの
呼び出しでないため拒否されました

が出力されてしまったので、Permissionsの変更が必要でした。manifest.json に clipboardWrite を追加することで動作するようになりました。

manifest.json抜粋
    "permissions": [
        "contextMenus",
        "storage",
        "tabs",
        "clipboardWrite",
        "http://*/*"
    ],

参考

クリップボードとのやりとり - Mozilla | MDN
document.createElement - Web API インターフェイス | MDN
Copying text to clipboard with JavaScript – Hacker Noon