web-dev-qa-db-ja.com

document.execCommand( 'copy')が機能していませんChrome

On Chrome only document.execCommand('copy')はtrueを返しますが、テキストをコピーせず、クリップボードをクリアします。

同じ問題を抱えている人を見つけることはできません。同様の質問がたくさんありますが、本当にそうでない限り、これを重複としてマークしないでください。

  • selection.removeAllRanges()の前にselection.addRange()を呼び出しています。
  • selection.getRangeAt(0).cloneContents()は、正しいテキストを含むフラグメントを返します
  • テキストエリアのテキストが選択されていないようです
  • textarea.select()の前にdocument.execCommand('copy')を呼び出すと、テキストが選択されて表示され、クリップボードにコピーされます。 textareaにフォーカスし、ページをスクロールさせるので、これを行いたくありません。
  • テスト済みChrome 61および63、MacOS
  • Safariでの作業

これが私のコードです(クリックイベントリスナー内で使用)
https://codepen.io/jakecr/pen/XVXvKz

var textarea = document.createElement('textarea');
textarea.textContent = 'coppied text';
document.body.appendChild(textarea);

var selection = document.getSelection();
var range = document.createRange();
range.selectNodeContents(textarea);
selection.removeAllRanges();
selection.addRange(range);

// DOESN'T WORK WITHOUT THIS
// textarea.select();

console.log(selection.getRangeAt(0).cloneContents());
console.log('copy success', document.execCommand('copy'));
7
Jake

ここで実際に何が起こっているのか、私にはよくわかりません...

テキストエリアのvalueプロパティとtextContentプロパティの間に使用すべきものが一致していないようです。
Chromeは常にvalueを使用するようですが、FirefoxはtextContentを使用します。

btn.onclick = e => {
  const txt = document.createElement('textarea');
  document.body.appendChild(txt);
  txt.value = 'from value'; // chrome uses this
  txt.textContent = 'from textContent'; // FF uses this
  var sel = getSelection();
  var range = document.createRange();
  range.selectNode(txt);
  sel.removeAllRanges();
  sel.addRange(range);
  if(document.execCommand('copy')){
    console.log('copied');
  }
  document.body.removeChild(txt);
}
<button id="btn">Copy!</button>
<textarea>You can paste here

</textarea>

chromeはtextContentプロパティを見ないので、Range#selectNodeContentsこのブラウザでは何も選択しません...

ただし、Range#selectNodeを使用できます。この場合、同じ結果が返され、問題を回避できます。

document.getElementById('btn').addEventListener('click', function(){
  var textarea = document.createElement('textarea');
  textarea.textContent = 'copied text';
  document.body.appendChild(textarea);

  var selection = document.getSelection();
  var range = document.createRange();
//  range.selectNodeContents(textarea);
  range.selectNode(textarea);
  selection.removeAllRanges();
  selection.addRange(range);

  console.log('copy success', document.execCommand('copy'));
  selection.removeAllRanges();

  document.body.removeChild(textarea);
  
})
<button id="btn">copy</button>
<textarea>You can paste here</textarea>
20
Kaiido

入力フィールドを動的に挿入し、テキストを挿入してから、クリップボードにコピーできないことがわかりました。既存の入力タグからテキストをコピーできました。

0
voodoologic