【Arc】Arc Windowsでnavigator.clipboard.writeTextが動かない時の対処法
TL;DR
- Arc Browser(Windows版)で
navigator.clipboard.writeTextが正常に動作しない問題に遭遇 - コンソールでは正しく値が取れているのに、クリップボードには一部しかコピーされない
-
document.execCommand('copy')を使うことで解決
はじめに
Arc Browser(Windows版)を使ってブックマークレット or スクリプトを作成してみようかなと思っていたときに、クリップボード周りで予期しない動作に遭遇したので、その備忘録です。
Arcはブックマークの概念が存在しないため、最終的にコンソールからのスクリプト実行に落ち着きました。よりよい方法・問題点があればご指摘ください。
遭遇した問題
Webページから複数の情報を取得してクリップボードにコピーするブックマークレットを作成しました。
(function(){
const text1 = document.querySelector('.some-class')?.innerText?.trim() || '取得失敗';
const text2 = window.location.href;
const result = `情報1: ${text1}\n情報2: ${text2}`;
navigator.clipboard.writeText(result).then(() => {
alert('コピー完了!\n\n' + result);
});
})();
症状
- コンソールで
console.log(result)すると正しく全ての情報が表示される - アラートでも全文が表示される
- しかし実際にクリップボードにコピーされるのは最初の1行だけ
- エラーは出ない
# 期待する結果
情報1: サンプルテキスト
情報2: https://example.com/page
# 実際にコピーされた内容
情報1: サンプルテキスト
デバッグプロセス
1. 変数の中身を確認
(function(){
const text1 = document.querySelector('.some-class')?.innerText?.trim() || '取得失敗';
const text2 = window.location.href;
const result = `情報1: ${text1}\n情報2: ${text2}`;
console.log('--- デバッグ情報 ---');
console.log('text1:', text1);
console.log('text2:', text2);
console.log('result:', result);
console.log('result length:', result.length);
console.log('改行を含む:', result.includes('\n'));
})();
結果:
text1: サンプルテキスト
text2: https://example.com/page
result: 情報1: サンプルテキスト
情報2: https://example.com/page
result length: 73
改行を含む: true
変数には正しく全文が入っている → Clipboard APIの問題???
2. 改行コードを変更してみる
Windows環境では \r\n が必要かと思い試してみましたが、改善せず。
const result = '情報1: ' + text1 + '\r\n情報2: ' + text2;
解決方法:document.execCommand を使う
Arc WindowsのClipboard API実装に問題があるようなので、古い方式の document.execCommand('copy') を使うことで解決しました。
修正後のコード
(function(){
const text1 = document.querySelector('.some-class')?.innerText?.trim() || '取得失敗';
const text2 = window.location.href;
const result = '情報1: ' + text1 + '\r\nURL: ' + text2;
// 一時的なtextarea要素を作成
const textarea = document.createElement('textarea');
textarea.value = result;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
try {
const success = document.execCommand('copy');
if (success) {
alert('コピー完了!\n\n' + result);
} else {
prompt('以下を手動でコピーしてください:', result);
}
} catch (err) {
prompt('以下を手動でコピーしてください:', result);
} finally {
document.body.removeChild(textarea);
}
})();
ポイント
-
非表示のtextarea要素を作成
-
position: fixedとopacity: 0で画面に表示させない
-
-
select() でテキストを選択状態にする
- これがないとコピーできない
-
execCommand('copy') で確実にコピー
- 戻り値で成功/失敗を判定できる
-
最後に要素を削除
-
finallyで確実にクリーンアップ
-
より堅牢な実装:両方試す
Clipboard APIが使える環境では使い、ダメならフォールバックする方式:
(function(){
const text1 = document.querySelector('.some-class')?.innerText?.trim() || '取得失敗';
const text2 = window.location.href;
const result = '情報1: ' + text1 + '\r\n情報2: ' + text2;
// 方法1: Clipboard API(モダン)
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(result)
.then(() => {
alert('コピー完了!\n\n' + result);
})
.catch(() => {
fallbackCopy();
});
} else {
// 方法2: execCommand(古いが確実)
fallbackCopy();
}
function fallbackCopy() {
const textarea = document.createElement('textarea');
textarea.value = result;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
alert('コピー完了!\n\n' + result);
} catch (err) {
prompt('以下を手動でコピーしてください:', result);
} finally {
document.body.removeChild(textarea);
}
}
})();
ブックマークレット化
Arc Windowsのブックマークレットの設定方法が分かりません。今回は趣味程度だったので、ここまで。時間があったら調査してみようと思います。
他のブラウザでは、使用可能かもしれません。
上記のコードを1行に圧縮してブックマークのURLに設定:
javascript:(function(){const text1=document.querySelector('.some-class')?.innerText?.trim()||'取得失敗';const text2=window.location.href;const result='情報1: '+text1+'\r\n情報2: '+text2;const textarea=document.createElement('textarea');textarea.value=result;textarea.style.position='fixed';textarea.style.opacity='0';document.body.appendChild(textarea);textarea.select();try{const success=document.execCommand('copy');if(success){alert('✅ コピー完了!\n\n'+result);}else{prompt('以下を手動でコピーしてください:',result);}}catch(err){prompt('以下を手動でコピーしてください:',result);}finally{document.body.removeChild(textarea);}})();
応用例
このテクニックは様々な場面で使えます(参考程度にどうぞ):
例1:ページタイトルとURLをコピー
javascript:(function(){const title=document.title;const url=window.location.href;const text=title+'\n'+url;const t=document.createElement('textarea');t.value=text;t.style.position='fixed';t.style.opacity='0';document.body.appendChild(t);t.select();document.execCommand('copy');document.body.removeChild(t);alert('コピー完了!\n\n'+text);})();
例2:選択したテキストにURLを追加
javascript:(function(){const selected=window.getSelection().toString();const url=window.location.href;const text=selected+'\n\n出典: '+url;const t=document.createElement('textarea');t.value=text;t.style.position='fixed';t.style.opacity='0';document.body.appendChild(t);t.select();document.execCommand('copy');document.body.removeChild(t);alert('引用をコピーしました');})();
例3:複数の要素を一括コピー
javascript:(function(){const items=Array.from(document.querySelectorAll('.item-title')).map(el=>el.innerText).join('\n');const t=document.createElement('textarea');t.value=items;t.style.position='fixed';t.style.opacity='0';document.body.appendChild(t);t.select();document.execCommand('copy');document.body.removeChild(t);alert(items.split('\n').length+'件コピーしました');})();
なぜこの問題が起きるのか
【確認方法】Clipboard APIが使えるブラウザか?
コンソールにて実行してみました。
'navigator.clipboard' in navigator // → true/false
結果→false
Clipboard APIの仕様
navigator.clipboard.writeText は比較的新しいAPIで、ブラウザによって実装が異なります。
- 権限管理が厳格:ユーザーの明示的な操作が必要
- セキュリティ制約:HTTPS必須、一部の環境では制限あり
- 実装の差:ブラウザごとに挙動が異なる
Arc Browser(特にWindows版)は独自のセキュリティポリシーにより、Clipboard APIの動作が標準と異なる可能性があります。
(Chromiumのフォークの具合もある??)
execCommandの利点
- 古い技術:ほぼ全てのブラウザで動作
- 権限不要:ユーザー操作なしでも動作
- 確実性:戻り値で成功/失敗を判定可能
ただし、execCommandは 非推奨(deprecated) なので、将来的には使えなくなる可能性があります。
まとめ
- Arc Windowsでは
navigator.clipboard.writeTextが正常に動作しないケースがある -
document.execCommand('copy')を使えば確実にコピーできる - 両方を組み合わせてフォールバックする実装が最も堅牢
- ブックマークレットとして活用すれば、様々な作業を効率化できる
現在Arcの後継であるDiaがMacのみしか使えないので、Windows版も使用してみたいですね。
Discussion