web-dev-qa-db-ja.com

JavaScriptでクリップボードにコピーする方法

テキストをクリップボードにコピーするための最良の方法は何ですか? (マルチブラウザ)

私が試してみました:

function copyToClipboard(text) {
    if (window.clipboardData) { // Internet Explorer
        window.clipboardData.setData("Text", text);
    } else {  
        unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  
        const clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);  
        clipboardHelper.copyString(text);
    }
}

しかし、Internet Explorerでは構文エラーが発生します。 Firefoxでは、それはunsafeWindow is not definedと言います。

フラッシュせずにいいトリック: どのようにTrelloはユーザーのクリップボードにアクセスしますか?

2930

概要

クリップボードにコピーするための3つの主要なブラウザAPIがあります。

  1. 非同期クリップボードAPI[navigator.clipboard.writeText]
    • テキスト中心の部分は Chrome 66(2018年3月) にあります
    • アクセスは非同期で、 JavaScript Promises を使用します。セキュリティユーザーのプロンプト(表示されている場合)がページ内のJavaScriptに割り込まないようにすることができます。
    • テキストは変数から直接クリップボードにコピーできます。
    • HTTPS経由で提供されているページでのみサポートされます。
    • Chromeでは、アクティブタブ内の66ページが、許可なしにクリップボードに書き込むことができます。
  2. document.execCommand('copy')
    • 2015年4月現在、ほとんどのブラウザでこれがサポートされています(下記のブラウザサポートを参照)。
    • アクセスは同期的です。つまり、表示やユーザーによるセキュリティプロンプトの操作が完了するまで、ページ内のJavaScriptを停止します。
    • テキストはDOMから読み取られ、クリップボードに配置されます。
    • 2015年4月のテスト中、Internet Explorerのみがクリップボードへの書き込み中にアクセス権のプロンプトを表示すると表示されました。
  3. コピーイベントを上書きする
    • コピーイベントの上書き のクリップボードAPIドキュメントを参照してください。
    • コピーイベントからクリップボードに表示される内容を変更したり、プレーンテキスト以外の形式のデータを含めることができます。
    • 質問に直接回答しないため、ここでは説明しません。

一般開発ノート

コンソールでコードをテストしている間は、クリップボード関連のコマンドが機能するとは思わないでください。一般に、ページはアクティブ(Async Clipboard API)である必要があるか、または(document.execCommand('copy'))がクリップボードにアクセスできるようにするためにユーザーの操作(例えば、ユーザークリック)を必要とします。

非同期+フォールバック

新しいAsync Clipboard APIに対するブラウザサポートのレベルのために、あなたは良いブラウザカバレッジを得るためにdocument.execCommand('copy')メソッドにフォールバックしたくなるでしょう。

これは簡単な例です:

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Fallback: Copying text command was ' + msg);
  } catch (err) {
    console.error('Fallback: Oops, unable to copy', err);
  }

  document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
  if (!navigator.clipboard) {
    fallbackCopyTextToClipboard(text);
    return;
  }
  navigator.clipboard.writeText(text).then(function() {
    console.log('Async: Copying to clipboard was successful!');
  }, function(err) {
    console.error('Async: Could not copy text: ', err);
  });
}

var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

このスニペットは、Stack Overflowの埋め込みプレビューではうまく機能しないことに注意してください。ここで試すことができます。 https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors=1011

非同期クリップボードAPI

Chrome 66の「Permissions」を使用して「許可を要求」し、クリップボードへのアクセスをテストする機能があります。

var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
  console.log('Async: Copying to clipboard was successful!');
}, function(err) {
  console.error('Async: Could not copy text: ', err);
});

document.execCommand( 'copy')

この記事の残りの部分では、document.execCommand('copy') APIの詳細と詳細について説明します。

ブラウザのサポート

JavaScript document.execCommand('copy') サポートが拡大しました。ブラウザの更新については以下のリンクを参照してください。

簡単な例

var copyTextareaBtn = document.querySelector('.js-textareacopybtn');

copyTextareaBtn.addEventListener('click', function(event) {
  var copyTextarea = document.querySelector('.js-copytextarea');
  copyTextarea.focus();
  copyTextarea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }
});
<p>
  <button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
  <textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>

複雑な例:入力を表示せずにクリップボードにコピーする

上記の簡単な例は、textareaまたはinput要素が画面に表示されている場合に非常に役立ちます。

場合によっては、input/textarea要素を表示せずにテキストをクリップボードにコピーしたいことがあります。これはこれを回避する方法の一例です(基本的に要素の挿入、クリップボードへのコピー、要素の削除)。

Google Chrome 44、Firefox 42.0a1、およびInternet Explorer 11.0.8600.17814でテスト済み。

function copyTextToClipboard(text) {
  var textArea = document.createElement("textarea");

  //
  // *** This styling is an extra step which is likely not required. ***
  //
  // Why is it here? To ensure:
  // 1. the element is able to have focus and selection.
  // 2. if element was to flash render it has minimal visual impact.
  // 3. less flakyness with selection and copying which **might** occur if
  //    the textarea element is not visible.
  //
  // The likelihood is the element won't even render, not even a
  // flash, so some of these are just precautions. However in
  // Internet Explorer the element is visible whilst the popup
  // box asking the user for permission for the web page to
  // copy to the clipboard.
  //

  // Place in top-left corner of screen regardless of scroll position.
  textArea.style.position = 'fixed';
  textArea.style.top = 0;
  textArea.style.left = 0;

  // Ensure it has a small width and height. Setting to 1px / 1em
  // doesn't work as this gives a negative w/h on some browsers.
  textArea.style.width = '2em';
  textArea.style.height = '2em';

  // We don't need padding, reducing the size if it does flash render.
  textArea.style.padding = 0;

  // Clean up any borders.
  textArea.style.border = 'none';
  textArea.style.outline = 'none';
  textArea.style.boxShadow = 'none';

  // Avoid flash of white box if rendered for any reason.
  textArea.style.background = 'transparent';


  textArea.value = text;

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }

  document.body.removeChild(textArea);
}


var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

その他の注意事項

ユーザーがアクションを実行した場合にのみ機能します

すべてのdocument.execCommand('copy')呼び出しは、ユーザーアクションの直接の結果として行われる必要があります。イベントハンドラをクリックします。これは、ユーザーが予期しないときにユーザーのクリップボードをめちゃくちゃにするのを防ぐための措置です。

詳しくは Google Developersの投稿を参照してください

クリップボードAPI

Clipboard APIのドラフト仕様の全文はここにあります。 https://w3c.github.io/clipboard-apis/

サポートされていますか?

  • コマンドが "ブラウザでサポートされている"場合、document.queryCommandSupported('copy')trueを返します。
  • document.queryCommandEnabled('copy')が今呼び出された場合に成功する場合、document.execCommand('copy')trueを返します。ユーザーが開始したスレッドからコマンドが呼び出されたこと、およびその他の要件が満たされていることを確認するためのチェック。

ただし、ブラウザ互換性の問題の例として、2015年4月から10月までのGoogle Chromeは、ユーザーが開始したスレッドからコマンドが呼び出された場合にのみdocument.queryCommandSupported('copy')からtrueを返しました。

下記の互換性の詳細に注意してください。

ブラウザ互換性の詳細

ユーザーのクリックの結果として呼び出されるtry/catchブロックでラップされたdocument.execCommand('copy')への単純な呼び出しは、あなたに最も互換性を持たせるでしょうが、以下にいくつかの条件があります。

document.execCommanddocument.queryCommandSupported、またはdocument.queryCommandEnabledへの呼び出しはすべてtry/catchブロックでラップする必要があります。

ブラウザの実装やバージョンが異なれば、falseを返すのではなく、呼び出されると異なる種類の例外が発生します。

さまざまなブラウザの実装がまだ流動的で、 Clipboard API がまだドラフトの中にあるので、テストをすることを忘れないでください。

1789
Dean Taylor

クリップボードへの自動コピーは危険な場合があるため、ほとんどのブラウザ(IEを除く)では非常に困難です。個人的には、次のような簡単なトリックを使います。

function copyToClipboard(text) {
  window.Prompt("Copy to clipboard: Ctrl+C, Enter", text);
}

コピーするテキストがすでに選択されているプロンプトボックスが表示されます。今押すことで十分です Ctrl+C そして Enter (箱を閉じるために) - そして、ほら!

これで、クリップボードのコピー操作は安全になりました。これは、ユーザーが手動で行うためです(ただし、かなり簡単な方法で)。もちろん、すべてのブラウザで動作します。

<button id="demo" onclick="copyToClipboard(document.getElementById('demo').innerHTML)">This is what I want to copy</button>

<script>
  function copyToClipboard(text) {
    window.Prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
</script>
1228
Jarek Milewski

次の方法は、Chrome、Firefox、Internet Explorer、Edge、および最近のバージョンのSafari(2016年10月にリリースされたバージョン10でコピーサポートが追加されました)で機能します。

  • テキストエリアを作成し、その内容をクリップボードにコピーしたいテキストに設定します。
  • テキストエリアをDOMに追加します。
  • テキストエリアのテキストを選択します。
  • Document.execCommand( "copy")を呼び出します。
  • DOMからテキストエリアを削除します。

注意:textareaは、JavaScriptコードの同じ同期呼び出し内で追加および削除されるため、表示されません。

これを自分で実装している場合には注意が必要な点がいくつかあります。

  • セキュリティ上の理由から、これはclickなどのイベントハンドラからのみ呼び出すことができます(ウィンドウを開くときと同じ)。
  • クリップボードが最初に更新されるときに、IEは許可ダイアログを表示します。
  • テキストエリアにフォーカスがあると、IEとEdgeがスクロールします。
  • execCommand()がスローすることがあります。
  • テキストエリアを使用しない限り、改行とタブが飲み込まれることがあります。 (ほとんどの記事ではdivの使用を推奨しているようです)
  • IEダイアログが表示されている間はテキストエリアが表示されます。非表示にするか、IE固有のclipboardData apiを使用する必要があります。
  • IEでは、システム管理者はクリップボードAPIを無効にすることができます。

以下の関数は、以下の問題すべてを可能な限りきれいに処理します。あなたが何か問題を見つけたりそれを改善するための何か提案があればコメントを残してください。

// Copies a string to the clipboard. Must be called from within an 
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+, 
// Firefox 42+, Safari 10+, Edge and IE 10+.
// IE: The clipboard feature may be disabled by an administrator. By
// default a Prompt is shown the first time the clipboard is 
// used (per session).
function copyToClipboard(text) {
    if (window.clipboardData && window.clipboardData.setData) {
        // IE specific code path to prevent textarea being shown while dialog is visible.
        return clipboardData.setData("Text", text); 

    } else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
        var textarea = document.createElement("textarea");
        textarea.textContent = text;
        textarea.style.position = "fixed";  // Prevent scrolling to bottom of page in MS Edge.
        document.body.appendChild(textarea);
        textarea.select();
        try {
            return document.execCommand("copy");  // Security exception may be thrown by some browsers.
        } catch (ex) {
            console.warn("Copy to clipboard failed.", ex);
            return false;
        } finally {
            document.body.removeChild(textarea);
        }
    }
}

https://jsfiddle.net/fx6a6n6x/ /

221
Greg Lowe

あなたが本当に簡単な解決策(統合するのに5分もかからない)を望み、箱から出してすぐに良さそうに見えるなら、 Clippy はより複雑な解決策のいくつかに対する素晴らしい代替案です。

GitHubの共同創設者によって書かれました。以下のFlash埋め込みコードの例:

<object
   classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
   width="110"
   height="14"
   id="clippy">
  <param name="movie" value="/flash/clippy.swf"/>
  <param name="allowScriptAccess" value="always"/>
  <param name="quality" value="high"/>
  <param name="scale" value="noscale"/>
  <param NAME="FlashVars" value="text=#{text}"/>
  <param name="bgcolor" value="#{bgcolor}"/>
  <embed
     src="/flash/clippy.swf"
     width="110"
     height="14"
     name="clippy"
     quality="high"
     allowScriptAccess="always"
     type="application/x-shockwave-flash"
     pluginspage="http://www.macromedia.com/go/getflashplayer"
     FlashVars="text=#{text}"
     bgcolor="#{bgcolor}"/>
</object>

#{text}をコピーしたいテキストに、#{bgcolor}を色に置き換えてください。

93
Brent Matzelle

Webページからクリップボードを読み取って変更すると、セキュリティとプライバシーの問題が発生します。しかし、Internet Explorerでは、それは可能です。私はこれを見つけました サンプルスニペット

    <script type="text/javascript">
        function select_all(obj) {
            var text_val=eval(obj);
            text_val.focus();
            text_val.select();
            r = text_val.createTextRange();
            if (!r.execCommand) return; // feature detection
            r.execCommand('copy');
        }
    </script>
    <input value="http://www.sajithmr.com"
     onclick="select_all(this)" name="url" type="text" />

80
bandi

私は最近この問題について 技術ブログ投稿 を書きました(私はLucidchartで働いていて、最近クリップボードのオーバーホールを行いました)。

プレーンテキストをクリップボードにコピーするのは比較的簡単です。システムコピーイベント中にコピーを行いたいと仮定すると(ユーザーによる CtrlC またはブラウザのメニューを使用します。

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 
           || navigator.userAgent.toLowerCase().indexOf("trident") != -1);

document.addEventListener('copy', function(e) {
    var textToPutOnClipboard = "This is some text";
    if (isIe) {
        window.clipboardData.setData('Text', textToPutOnClipboard);    
    } else {
        e.clipboardData.setData('text/plain', textToPutOnClipboard);
    }
    e.preventDefault();
});

システムのコピーイベント中ではなく、クリップボードにテキストを配置するのははるかに困難です。他のいくつかの回答では、Flashを介してそれを実行する方法を参照しているように見えます。

それ以外に、ブラウザごとにいくつかのオプションがあります。

これはIEで最も簡単な方法で、JavaScriptからいつでもclipboardDataオブジェクトにアクセスできます。

window.clipboardData

(ただし、システムの切り取り、コピー、貼り付けなどのイベント以外でこれを実行しようとすると、IEによってWebアプリケーションのクリップボードへのアクセス許可が付与されます。)

Chromeでは、 クリップボードのアクセス許可 (これがLucidchartのためにしていることです)を与えるChrome拡張機能を作成することができます。拡張機能がインストールされているユーザーの場合は、システムイベントを自分で起動するだけです。

document.execCommand('copy');

Firefoxが いくつかのオプション を持っているように見えますが、クリップボードにアクセスするために特定のサイトにユーザーに許可を与えることができますが、私は個人的に試していません。

67
Richard Shurtz

これが私の考えです。

function copy(text) {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input)
    return result;
 }
44
nikksan

clipboard.js は、テキストやHTMLデータをクリップボードにコピーできる、Flash以外の小型のユーティリティです。使い方はとても簡単です。単に.jsをインクルードして次のようなものを使うだけです。

<button id='markup-copy'>Copy Button</button>

<script>
document.getElementById('markup-copy').addEventListener('click', function() {
  clipboard.copy({
    'text/plain': 'Markup text. Paste me into a rich text editor.',
    'text/html': '<i>here</i> is some <b>rich text</b>'
  }).then(
    function(){console.log('success'); },
    function(err){console.log('failure', err);
  });

});
</script>

clipboard.jsは GitHub にもあります。

注: これは現在推奨されていません。 here に移行します。

44
a coder

ZeroClipboardは私が見つけた最高のクロスブラウザソリューションです。

<div id="copy" data-clipboard-text="Copy Me!">Click to copy</div>    
<script src="ZeroClipboard.js"></script>
<script>
  var clip = new ZeroClipboard( document.getElementById('copy') );
</script>

あなたがiOSのための非フラッシュサポートを必要とするならば、あなたはただフォールバックを加える:

clip.on( 'noflash', function ( client, args ) {
    $("#copy").click(function(){            
        var txt = $(this).attr('data-clipboard-text');
        Prompt ("Copy link, then click OK.", txt);
    });
});  

http://zeroclipboard.org/ /

https://github.com/zeroclipboard/ZeroClipboard

34
Justin

私が取り組んでいるプロジェクトの1つで、 Zero Clipboard ライブラリを利用するjQueryのクリップボードへのコピープラグイン。

あなたがヘビーなjQueryユーザーであれば、ネイティブのゼロクリップボードプラグインよりも使いやすいです。

25
SteamDev

私は以下の解決策を見つけました:

キーダウン時にハンドラが "pre"タグを作成します。このタグにコピーするコンテンツを設定してから、このタグで選択を行い、ハンドラにtrueを返します。これは標準のchromeハンドラを呼び出し、選択されたテキストをコピーします。

また、必要に応じて、以前の選択を復元するための機能のタイムアウトを設定することができます。 Mootoolsで私の実装:

   function EnybyClipboard() {
     this.saveSelection = false;
     this.callback = false;
     this.pastedText = false;

     this.restoreSelection = function() {
       if (this.saveSelection) {
         window.getSelection().removeAllRanges();
         for (var i = 0; i < this.saveSelection.length; i++) {
           window.getSelection().addRange(this.saveSelection[i]);
         }
         this.saveSelection = false;
       }
     };

     this.copyText = function(text) {
       var div = $('special_copy');
       if (!div) {
         div = new Element('pre', {
           'id': 'special_copy',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
       }
       div.set('text', text);
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         setTimeout(this.restoreSelection.bind(this), 100);
       } else return alert('Copy not work. :(');
     };

     this.getPastedText = function() {
       if (!this.pastedText) alert('Nothing to paste. :(');
       return this.pastedText;
     };

     this.pasteText = function(callback) {
       var div = $('special_paste');
       if (!div) {
         div = new Element('textarea', {
           'id': 'special_paste',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
         div.addEvent('keyup', function() {
           if (this.callback) {
             this.pastedText = $('special_paste').get('value');
             this.callback.call(null, this.pastedText);
             this.callback = false;
             this.pastedText = false;
             setTimeout(this.restoreSelection.bind(this), 100);
           }
         }.bind(this));
       }
       div.set('value', '');
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         div.focus();
         this.callback = callback;
       } else return alert('Fail to paste. :(');
     };
   }

使用法:

enyby_clip = new EnybyClipboard(); //init 

enyby_clip.copyText('some_text'); // place this in CTRL+C handler and return true;

enyby_clip.pasteText(function callback(pasted_text) {
        alert(pasted_text);
}); // place this in CTRL+V handler and return true;

貼り付けるとテキストエリアが作成され、同じように機能します。

PSは、このソリューションはフラッシュなしで完全にクロスブラウザソリューションを作成するために使用することができます。 FFとChromeで動作します。

21
Enyby

Geesh、なぜだれもまだこれを指していないのかわかりません。

2018年、皆さん、これをどうやって進めることができるかを説明します。

async copySomething(text?) {
  try {
    const toCopy = text || location.href;
    await navigator.clipboard.writeText(toCopy);
    console.log('Text or Page URL copied');
  } catch (err) {
    console.error('Failed to copy: ', err);
  }
}

私のAngular 6+コードではこんな感じで使われています:

<button mat-menu-item (click)="copySomething()">
    <span>Copy link</span>
</button>

文字列を渡すと、それがコピーされます。何もなければ、ページのURLをコピーします。

クリップボードのものにもっと体操をすることもできます。詳細はこちらをご覧ください。

https://developers.google.com/web/updates/2018/03/clipboardapi

21
Rexford

他の方法はプレーンテキストをクリップボードにコピーします。 HTMLをコピーする(つまり、WSIWYGエディタに結果を貼り付けることができます)には、 IE ONLY で次の操作を行います。ブラウザは実際に視覚的にコンテンツを選択するため、これは他の方法とは根本的に異なります。

// create an editable DIV and append the HTML content you want copied
var editableDiv = document.createElement("div");
with (editableDiv) {
    contentEditable = true;
}     
editableDiv.appendChild(someContentElement);          

// select the editable content and copy it to the clipboard
var r = document.body.createTextRange();
r.moveToElementText(editableDiv);
r.select();  
r.execCommand("Copy");

// deselect, so the browser doesn't leave the element visibly selected
r.moveToElementText(someHiddenDiv);
r.select();   
19
Chase Seibert

私はこれを非常にうまく使っています( without jqueryまたは他のフレームワーク)。

function copyToClp(txt){
    txt = document.createTextNode(txt);
    var m = document;
    var w = window;
    var b = m.body;
    b.appendChild(txt);
    if (b.createTextRange) {
        var d = b.createTextRange();
        d.moveToElementText(txt);
        d.select();
        m.execCommand('copy');
    } else {
        var d = m.createRange();
        var g = w.getSelection;
        d.selectNodeContents(txt);
        g().removeAllRanges();
        g().addRange(d);
        m.execCommand('copy');
        g().removeAllRanges();
    }
    txt.remove();
} 

警告

タブはスペースに変換されます(少なくともクロム)。

18
Peter Rader

最近からChrome 42+Firefox 41+ document.execCommand( 'copy') コマンドをサポートします。そこで、 Tim Downの古い答え および Google Developerの答え の組み合わせを使用して、クロスブラウザからクリップボードへのコピー機能用の関数をいくつか作成しました。

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // IE 
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
        textRange.execCommand("Copy");
    } else if (window.getSelection && document.createRange) {
        // non-IE
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copy command was ' + msg);
        } catch (err) {
            console.log('Oops, unable to copy');
        }
    }
} // end function selectElementContents(el) 

function make_copy_button(el) {
    var copy_btn = document.createElement('input');
    copy_btn.type = "button";
    el.parentNode.insertBefore(copy_btn, el.nextSibling);
    copy_btn.onclick = function() {
        selectElementContents(el);
    };

    if (document.queryCommandSupported("copy") || parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 42) {
        // Copy works with IE 4+, Chrome 42+, Firefox 41+, Opera 29+
        copy_btn.value = "Copy to Clipboard";
    } else {
        // Select only for Safari and older Chrome, Firefox and Opera
        copy_btn.value = "Select All (then press CTRL+C to Copy)";
    }
}
/* Note: document.queryCommandSupported("copy") should return "true" on browsers that support copy
	but there was a bug in Chrome versions 42 to 47 that makes it return "false".  So in those
	versions of Chrome feature detection does not work!
	See https://code.google.com/p/chromium/issues/detail?id=476508
*/

make_copy_button(document.getElementById("markup"));
<pre id="markup">
  Text that can be copied or selected with cross browser support.
</pre>

18
Jeff Baker

  <!DOCTYPE html>

  <style>
    #t {
      width: 1px
      height: 1px
      border: none
    }
    #t:focus {
      outline: none
    }
  </style>

  <script>
    function copy(text) {
      var t = document.getElementById('t')
      t.innerHTML = text
      t.select()
      try {
        var successful = document.execCommand('copy')
        var msg = successful ? 'successfully' : 'unsuccessfully'
        console.log('text coppied ' + msg)
      } catch (err) {
        console.log('Unable to copy text')
      }
      t.innerHTML = ''
    }
  </script>

  <textarea id=t></textarea>

  <button onclick="copy('hello world')">
    Click me
  </button>

12
Samuel Tees

Flash 10以降、アクションがFlashオブジェクトとのユーザーインタラクションから発生した場合にのみクリップボードにコピーできます。 ( Adob​​eのFlash 10発表の関連セクションを読んでください

この問題を解決するには、コピーボタンの上にあるフラッシュオブジェクト、またはコピーを開始する要素を上書きします。 Zero Clipboardは現在、この実装では最高のライブラリです。経験豊富なFlash開発者は、自分のライブラリを作成したいだけかもしれません。

12
matthuhiggins

私は以下の解決策を見つけました:

テキストを隠し入力にしています。 setSelectionRangeは隠し入力では機能しないので、一時的に型をテキストに変更し、テキストをコピーしてから再度隠します。要素からテキストをコピーしたい場合は、それを関数に渡してその内容をターゲット変数に保存できます。

    jQuery('#copy').on('click', function () {
        copyToClipboard();
    });

    function copyToClipboard() {
        var target = jQuery('#hidden_text');

        // make it visible, so can be focused
        target.attr('type', 'text');
        target.focus();
        // select all the text
        target[0].setSelectionRange(0, target.val().length);

        // copy the selection
        var succeed;
        try {
            succeed = document.execCommand("copy");
        } catch (e) {
            succeed = false;
        }

        // hide input again
        target.attr('type', 'hidden');

        return succeed;
    }
11
Vassilis Pallas

HTML入力からクリップボードにテキストをコピーする

 
 function myFunction() {
  /* Get the text field */
   var copyText = document.getElementById("myInput");
 
   /* Select the text field */
   copyText.select();

   /* Copy the text inside the text field */
   document.execCommand("Copy");
 
   /* Alert the copied text */
   alert("Copied the text: " + copyText.value);
 }
 
 
 <!-- The text field -->
 <input type="text" value="Hello Friend" id="myInput">
 
 <!-- The button used to copy the text -->
<button onclick="myFunction()">Copy text</button>
 

注: document.execCommand()メソッドはIE9以前ではサポートされていません。

出典 W3Schools - テキストをクリップボードにコピー

10
Alexandru Sirbu

私は自分が一番いいと思うものをまとめました。

  • 直接スタイルではなく、cssTextを使用してIEの例外を回避します。
  • 選択があった場合は選択を復元します
  • 読み取り専用に設定して、キーボードがモバイルデバイスに表示されないようにする
  • それが通常execCommandをブロックするので実際にはたらくようにiOSのための回避策があります。

ここにあります:

const copyToClipboard = (function initClipboardText() {
  const textarea = document.createElement('textarea');

  // Move it off screen.
  textarea.style.cssText = 'position: absolute; left: -99999em';

  // Set to readonly to prevent mobile devices opening a keyboard when
  // text is .select()'ed.
  textarea.setAttribute('readonly', true);

  document.body.appendChild(textarea);

  return function setClipboardText(text) {
    textarea.value = text;

    // Check if there is any content selected previously.
    const selected = document.getSelection().rangeCount > 0 ?
      document.getSelection().getRangeAt(0) : false;

    // iOS Safari blocks programmtic execCommand copying normally, without this hack.
    // https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
    if (navigator.userAgent.match(/ipad|iPod|iphone/i)) {
      const editable = textarea.contentEditable;
      textarea.contentEditable = true;
      const range = document.createRange();
      range.selectNodeContents(textarea);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      textarea.setSelectionRange(0, 999999);
      textarea.contentEditable = editable;
    } else {
      textarea.select();
    }

    try {
      const result = document.execCommand('copy');

      // Restore previous selection.
      if (selected) {
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(selected);
      }

      return result;
    } catch (err) {
      return false;
    }
  };
})();
10
Dominic

IE以外のブラウザでは、クリップボードを操作するために小さなFlashオブジェクトを使う必要があります。

9
Quog

私は(Excelのような)からカスタムグリッド編集を構築し、Excelとの互換性と同じ問題を抱えていた。複数のセルの選択、コピー、貼り付けをサポートする必要がありました。

解決策:ユーザーがコピーするデータを挿入するテキストエリアを作成し(ユーザーがセルを選択しているときは私に)、フォーカスを設定します(たとえば、ユーザーが押すとき)。 Ctrl)とテキスト全体を選択します。

だから、ユーザーがヒットしたとき Ctrl + C 選択したセルがコピーされます。テスト後、テキストエリアを1ピクセルにリサイズするだけです(ディスプレイ上で動作するかどうかはテストしませんでした:なし)。これはすべてのブラウザでうまく機能し、ユーザーには見えません。

貼り付け - あなたはこれと同じことをすることができます(あなたのターゲットによって異なります) - onpasteを使ってtextareaに集中して貼り付けイベントをキャッチします(私のプロジェクトでは編集するためにセルでtextareaを使います)。

私は例(商業プロジェクト)を貼り付けることはできませんが、あなたはアイデアを得ます。

8
xiniu

私はclipboard.jsを使用しました

私達はnpmでそれを得ることができます

npm install clipboard --save

そしてまたowerに

bower install clipboard --save

使い方と例は https://zenorocha.github.io/clipboard.js/ にあります。

7
CodecPM

すでに多くの答えがありますが、私はそれを追加したいと思います(jQuery)。どのブラウザでも、モバイルのブラウザでも魅力的に動作します(つまり、セキュリティについてのプロンプトが表示されますが、受け入れたときは正常に動作します)。

function appCopyToClipBoard( sText )
{
 var oText = false,
     bResult = false;
 try
 {
  oText = document.createElement("textarea");
  $(oText).addClass('clipboardCopier').val(sText).insertAfter('body').focus();
  oText.select();
  document.execCommand("Copy");
  bResult = true;
 } catch(e) {}

 $(oText).remove();
 return bResult;
}

あなたのコードで:

if( !appCopyToClipBoard( 'Hai there! This is copied to the clipboard.' ))
 { alert('Sorry, copy to clipboard failed.'); }
7
Codebeat

これは@ Chaseの回答を拡張したものです。IE9のDIVだけでなく、IMAGE要素とTABLE要素に対しても機能するという利点があります。

if (document.createRange) {
    // IE9 and modern browsers
    var r = document.createRange();
    r.setStartBefore(to_copy);
    r.setEndAfter(to_copy);
    r.selectNode(to_copy);
    var sel = window.getSelection();
    sel.addRange(r);
    document.execCommand('Copy');  // does nothing on FF
} else {
    // IE 8 and earlier.  This stuff won't work on IE9.
    // (unless forced into a backward compatibility mode,
    // or selecting plain divs, not img or table). 
    var r = document.body.createTextRange();
    r.moveToElementText(to_copy);
    r.select()
    r.execCommand('Copy');
}
6
Oliver Bock

これは私が今までにインターネット上でいろいろな方法で調べた後に働いたことがある唯一のものでした。これは面倒な話題です。世界中にたくさんの解決策が掲載されていますが、そのほとんどは機能しません。これは私のために働いた:

注:このコードは 'onClick'メソッドのようなものに直接同期コードとして実行されたときにのみ機能します。あなたがajaxへの非同期応答または他の非同期の方法で呼び出すなら、それはうまくいかないでしょう

copyToClipboard(text) {
    var copyText = document.createElement("input");
    copyText.type = "text";
    document.body.appendChild(copyText);
    copyText.style = "display: inline; width: 1px;";
    copyText.value = text;
    copyText.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy");
    copyText.remove();
}

私は、このコードが1px幅のコンポーネントを1ミリ秒の間画面上に目に見えるように表示することを認識していますが、それについて心配することはしません。

5
user2080225

私はこの質問を誤解しているようですが、参考までに、DOMの範囲(クリップボードではない。最近のすべてのブラウザと互換性があります)を抽出し、クリップボードの動作を得るためにoncopyおよびonpasteとonbeforepasteイベントと組み合わせることができます。これを実現するためのコードは次のとおりです。 

function clipBoard(sCommand) {
  var oRange=contentDocument.createRange();
  oRange.setStart(startNode, startOffset);
  oRange.setEnd(endNode, endOffset);
/* This is where the actual selection happens.
in the above, startNode and endNode are dom nodes defining the beginning 
and end of the "selection" respectively. startOffset and endOffset are 
constants that are defined as follows:

END_TO_END: 2
END_TO_START: 3
NODE_AFTER: 1
NODE_BEFORE: 0
NODE_BEFORE_AND_AFTER: 2
NODE_INSIDE: 3
START_TO_END: 1
START_TO_START: 0

and would be used like oRange.START_TO_END */
      switch(sCommand) {
    case "cut":
          this.oFragment=oRange.extractContents();
      oRange.collapse();
      break;
    case "copy":
      this.oFragment=oRange.cloneContents();
      break;
    case "paste":
      oRange.deleteContents();
      var cloneFragment=this.oFragment.cloneNode(true)
      oRange.insertNode(cloneFragment);
      oRange.collapse();
      break;
  }
}
5
mrBorna

これは他の答えとのちょっとした組み合わせです。

var copyToClipboard = function(textToCopy){
    $("body")
        .append($('<input type="text" name="fname" class="textToCopyInput"/>' )
        .val(textToCopy))
        .find(".textToCopyInput")
        .select();
      try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        alert('Text copied to clipboard!');
      } catch (err) {
          window.Prompt("To copy the text to clipboard: Ctrl+C, Enter", textToCopy);
      }
     $(".textToCopyInput").remove();
}

JQueryを使用しますが、もちろんそうする必要はありません。必要に応じて変更できます。私はちょうど私の処分にjQueryを持っていました。入力が表示されないようにCSSを追加することもできます。たとえば、

.textToCopyInput{opacity: 0; position: absolute;}

もちろん、インラインスタイリングもできます。

.append($('<input type="text" name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )
5
Bart Burg

私の悪いこれはIEでのみ機能します。

これがテキストをコピーするもう一つの方法です:

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
5
dvallejo

選択したテキスト(「コピーするテキスト」)をクリップボードにコピーするには、ブックマークレット(Javsacriptを実行するブラウザのブックマーク)を作成して実行します(それをクリックします)。

Githubのコード:

https://Gist.github.com/stefanmaric/2abf96c740191cda3bc7a8b0fc905a7d

(function (text) {
  var node = document.createElement('textarea');
  var selection = document.getSelection();

  node.textContent = text;
  document.body.appendChild(node);

  selection.removeAllRanges();
  node.select();
  document.execCommand('copy');

  selection.removeAllRanges();
  document.body.removeChild(node);
})('Text To Copy');
5
Mau

ページから非入力ボックスのテキスト(div/spanタグ内のテキスト)をコピーする必要があり、次のコードを思い付きました。唯一のトリックは隠しフィールドを持つことですが、タイプTEXTのように、タイプが隠された状態では動作しません。 

    function copyToClipboard(sID) {
        var aField = document.getElementById("hiddenField");

        aField.hidden   = false;
        aField.value    = document.getElementById(sID).textContent;
        aField.select();
        document.execCommand("copy");
        alert("Following text has been copied to the clipboard.\n\n" + aField.value);
        aField.hidden = true;
    }

そしてHTMLに以下を追加してください

入力タイプ= "テキスト" id = "hiddenField"スタイル= "幅:5ピクセル;ボーダー:0" /> ...

4
NewToIOS

Greasemonkey\JavaScriptからクリップボードにコピーボタンのコードを使用したように見えます またはこのスニペットの元のソース...

このコードはGreasemonkey用であり、したがって安全でないウィンドウ用です。そして私はIEの構文エラーがFirefox特有のconstキーワードから来ていると思います(それをvarに置き換えます)。

4
PhiLho

私の知る限りでは、Internet Explorerでしか機能しません。

動的ツール - クリップボードへのJavaScriptコピーも参照。

4
Stormenet

セキュリティ上の理由から、それはできません。クリップボードにコピーするにはFlashを選択する必要があります。

私はこれを提案する: http://zeroclipboard.org/ /

3
sinister

私はclipboard.jsを使うつもりでしたが、まだモバイルソリューションはありません…それで私は超小型のライブラリを書きました:

https://github.com/ryanpcmcquen/cheval

これはテキスト(デスクトップ/ Android/Safari 10+)をコピーするか、少なくともテキスト(iOSの旧バージョン)を選択します。 1kBを少し超えただけです。デスクトップのSafari(コピーするにはCommand + Cキーを押す。それを使うのにJavaScriptを書く必要もない。

3
ryanpcmcquen

Chromeでは copy('the text or variable etc') を使用できます。これはクロスブラウザではありませんが(そして スニペットでは動作しません? )、他のクロスブラウザの回答に追加することができます。

2
drzaus

@ Jimbo、これは同じWebサイト用の簡単なAjax /セッションベースのクリップボードです。

セッションを有効にして有効にする必要があり、この解決策は同じサイトで機能することに注意してください。私はCodeIgniterでそれをテストしました、しかし、私はセッション/ Ajax問題に出くわしました、しかし これ /その問題も解決しました。セッションをしたくない場合は、データベーステーブルを使用してください。

JavaScript/jQuery

<script type="text/javascript">
    $(document).ready(function() {

        $("#copy_btn_id").click(function(){

            $.post("<?php echo base_url();?>ajax/foo_copy/"+$(this).val(), null,
                function(data){
                    // Copied successfully
                }, "html"
            );
        });

        $("#paste_btn_id").click(function() {

           $.post("<?php echo base_url();?>ajax/foo_paste/", null,
               function(data) {
                   $('#paste_btn_id').val(data);
               }, "html"
           );
        });
    });
</script>

HTMLコンテンツ

<input type='text' id='copy_btn_id' onclick='this.select();'  value='myvalue' />
<input type='text' id='paste_btn_id' value='' />

PHP code

<?php
    class Ajax extends CI_Controller {

        public function foo_copy($val){
            $this->session->set_userdata(array('clipboard_val' => $val));
        }

        public function foo_paste(){
            echo $this->session->userdata('clipboard_val');
            exit();
        }
    }
?>
2
Saad

更新2015:現在、document.execCommandを使用してクリップボードを操作する方法があります。 clipboard.js は、ブラウザ間でクリップボードを操作する方法を提供します( browser support

2

Dean Taylorによる最新の回答(2015年7月) に加えて、私は彼の例のようなjQueryメソッドを書きました。

jsFiddle

/**
* Copies the current selected text to the SO clipboard
* This method must be called from an event to work with `execCommand()`
* @param {String} text Text to copy
* @param {Boolean} [fallback] Set to true shows a Prompt
* @return Boolean Returns `true` if the text was copied or the user clicked on accept (in Prompt), `false` otherwise
*/
var CopyToClipboard = function(text, fallback){
    var fb = function () {
        $t.remove();
        if (fallback !== undefined && fallback) {
            var fs = 'Please, copy the following text:';
            if (window.Prompt(fs, text) !== null) return true;
        }
        return false;
    };
    var $t = $('<textarea />');
    $t.val(text).css({
        width: '100px',
        height: '40px'
    }).appendTo('body');
    $t.select();
    try {
        if (document.execCommand('copy')) {
            $t.remove();
            return true;
        }
        fb();
    }
    catch (e) {
        fb();
    }
};
2
kosmos

「clipboardRead」権限を許可して、Chrome拡張機能でクリップボードからテキストを読んでいる場合は、次のコードを使用できます。

function readTextFromClipboardInChromeExtension() {
    var ta = $('<textarea/>');
    $('body').append(ta);
    ta.focus();
    document.execCommand('paste');
    var text = ta.val();
    ta.blur();
    ta.remove();
    return text;
}
2
supNate

try/catchを使用してJavascript機能を使用すると、以下のようにすることでエラー処理をさらに改善することができます。

 copyToClipboard() {
     let el = document.getElementById('Test').innerText
     el.focus(); // el.select();
     try {
         var successful = document.execCommand('copy');
         if (successful) {
             console.log('Copied Successfully! Do whatever you want next');
         } else {
             throw ('Unable to copy');
         }
     } catch (err) {
         console.warn('Oops, Something went wrong ', err);
     }
 }
2
Adeel Imran

コピーしたリンクを同じサイトに貼り付ける必要がある場合は、単純なHTMLコピーボタンを押す前にテキストを強調表示し、それを押すとテキストコンテンツがセッションに保存されます。貼り付ける場所には、貼り付けボタンがあります。 

**私は知っている、それは永続的かつ普遍的な解決策ではないが、それは何か:)

2
Saad

すべてのケースをカバーするために、必要に応じてPromptフォールバックを使用して、いくつかの関数を単純なソリューションにまとめました。

window.copyToClipboard = function(text) {
  // IE specific
  if (window.clipboardData && window.clipboardData.setData) {
    return clipboardData.setData("Text", text);
  }

  // all other modern
  target = document.createElement("textarea");
  target.style.position = "absolute";
  target.style.left = "-9999px";
  target.style.top = "0";
  target.textContent = text;
  document.body.appendChild(target);
  target.focus();
  target.setSelectionRange(0, target.value.length);

  // copy the selection of fall back to Prompt
  try {
    document.execCommand("copy");
    target.remove();
    console.log('Copied to clipboard: "'+text+'"');
  } catch(e) {
    console.log("Can't copy string on this browser. Try to use Chrome, Firefox or Opera.")
    window.Prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
}

ここでテストしてください https://jsfiddle.net/jv0avz65/

1
dux

Safariや他のブラウザ(IE9 +)をサポートする解決策を探した後、

私はGithubと同じものを使います: ZeroClipboard

例:

http://zeroclipboard.org/index-v1.x.html

_ html _

<html>
  <body>
    <button id="copy-button" data-clipboard-text="Copy Me!" title="Click to copy me.">Copy to Clipboard</button>
    <script src="ZeroClipboard.js"></script>
    <script src="main.js"></script>
  </body>
</html>

_ js _

var client = new ZeroClipboard(document.getElementById("copy-button"));

client.on("ready", function (readyEvent) {
    // alert( "ZeroClipboard SWF is ready!" );

    client.on("aftercopy", function (event) {
        // `this` === `client`
        // `event.target` === the element that was clicked
        event.target.style.display = "none";
        alert("Copied text to clipboard: " + event.data["text/plain"]);
    });
});
1
user4912329

答えに私のものを追加するだけです。 

それは最高だ。とても勝ちました。 

var toClipboard = function(text) {
        var doc = document;

        // Create temp element
        var textarea = doc.createElement('textarea');
        textarea.style.position = 'absolute';
        textarea.style.opacity  = '0';
        textarea.textContent    = text;

        doc.body.appendChild(textarea);

        textarea.focus();
        textarea.setSelectionRange(0, textarea.value.length);

        // copy the selection
        var success;
        try {
                success = doc.execCommand("copy");
        } catch(e) {
                success = false;
        }

        textarea.remove();

        return success;
}
1
momomo

これは私のために働いた唯一のものでした:

let textarea = document.createElement('textarea');
textarea.setAttribute('type', 'hidden');
textarea.textContent = 'the string you want to copy';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
1
Alexander Mills

ここで@ dean-taylorによって提示された解決策を他の場所からの他の選択/選択解除コードと共にNPMで利用可能なjQueryプラグインにまとめました。

https://www.npmjs.com/package/jquery.text-select

インストール:

npm install --save jquery.text-select

使用法:

<script>
    $(document).ready(function(){
        $("#selectMe").selectText(); // Hightlight / select the text
        $("#selectMe").selectText(false); // Clear the selection

        $("#copyMe").copyText(); // Copy text to clipboard
    });
</script>

メソッド/イベントに関するさらなる情報は、上記のNPMレジストリページにあります。

0
Gruffy

document.execCommandを使うことはあなたのために仕事をするでしょう...

これを使って、 cut copy 、および paste もできます。

これは、入力テキストからすべてをコピーする簡単なクリップボードコピー機能です...

function copyInputText() {
  var copyText = document.querySelector("#input");
  copyText.select();
  document.execCommand("copy");
}

document.querySelector("#copy").addEventListener("click", copyInputText);
<input id="input" type="text" />
<button id="copy">Copy</button>

詳細については、 ここ をご覧ください。

0
Alireza

ここに簡単な例があります;)

<!DOCTYPE html>
<html>
<body>

<input type="text" value="Hello World" id="myInput">
<button onclick="myFunction()">Copy text</button>

<p>The document.execCommand() method is not supported in IE8 and earlier.</p>

<script>
function myFunction() {
  var copyText = document.getElementById("myInput");
  copyText.select();
  document.execCommand("copy");
  alert("Copied the text: " + copyText.value);
}
</script>

</body>
</html>
0
Lars Gross

これは、getElementbyId、Select()、blur()、およびcopyコマンドの組み合わせを使用するだけで実行できます。

注意

select()メソッドは、要素内のすべてのテキストまたはテキストフィールドを持つ要素を選択します。これはボタンでは動作しないかもしれません

使用法

let copyText = document.getElementById('input-field');
copyText.select()
document.execCommand("copy");
copyReferal.blur()
document.getElementbyId('help-text').textContent = 'Copied'

Blur()メソッドは、きれいなメッセージで コンテンツが正常にコピーされたことを示すことができる代わりに、見にくい部分を削除します

0
Nishant Singh

これはAngular 5.x +のエレガントな解決策です。

成分:

import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef,
  EventEmitter,
  Input,
  OnInit,
  Output,
  Renderer2,
  ViewChild
} from '@angular/core';

@Component({
  selector: 'copy-to-clipboard',
  templateUrl: './copy-to-clipboard.component.html',
  styleUrls: ['./copy-to-clipboard.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class CopyToClipboardComponent implements OnInit {
  @ViewChild('input') input: ElementRef;
  @Input() size = 'md';
  @Input() theme = 'complement';
  @Input() content: string;
  @Output() copied: EventEmitter<string> = new EventEmitter<string>();
  @Output() error: EventEmitter<string> = new EventEmitter<string>();

  constructor(private renderer: Renderer2) {}

  ngOnInit() {}

  copyToClipboard() {

    const rootElement = this.renderer.selectRootElement(this.input.nativeElement);

    // iOS Safari blocks programmtic execCommand copying normally, without this hack.
    // https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
    if (navigator.userAgent.match(/ipad|iPod|iphone/i)) {

      this.renderer.setAttribute(this.input.nativeElement, 'contentEditable', 'true');

      const range = document.createRange();

      range.selectNodeContents(this.input.nativeElement);

      const sel = window.getSelection();

      sel.removeAllRanges();
      sel.addRange(range);

      rootElement.setSelectionRange(0, 999999);
    } else {
      rootElement.select();
    }

    try {
      document.execCommand('copy');
      this.copied.emit();
    } catch (err) {
      this.error.emit(err);
    }
  };
}

テンプレート:

<button class="btn btn-{{size}} btn-{{theme}}" type="button" (click)="copyToClipboard()">
  <ng-content></ng-content>
</button>

<input #input class="hidden-input" [ngModel]="content">

スタイル:

.hidden-input {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px; 
  height: 1px;
  padding: 0;
  border: 0;
  box-shadow: none;
  outline: none;
  background: transparent;
}
0
Chrillewoodz

私は多くの解決策を試しました。最新のブラウザで動作する場合、IEでは動作しません。 IEで動作する場合、IOSでは動作しません。最終的にそれらすべてを手入れし、すべてのブラウザ、IOS、webview、およびAndroidで動作する以下の修正プログラムに到達しました。

注:ユーザーがクリップボードへのアクセス許可を拒否するシナリオについても説明しました。さらに、ユーザーが手動でコピーしても、「リンクがコピーされました」というメッセージが表示されます。

<div class="form-group col-md-12">
<div class="input-group col-md-9">
    <input name="copyurl"
           type="text"
           class="form-control br-0 no-focus"
           id="invite-url"
           placeholder="http://www.invitelink.com/example"
           readonly>
    <span class="input-group-addon" id="copy-link" title="Click here to copy the invite link">
        <i class="fa fa-clone txt-18 text-success" aria-hidden="true"></i>
    </span>
</div>
<span class="text-success copy-success hidden">Link copied.</span>

スクリプト:

var addEvent =  window.attachEvent || window.addEventListener;
var event = 'copy';
var $inviteUrl = $('#invite-url');

$('#copy-link').on('click', function(e) {
    if ($inviteUrl.val()) {
        if (navigator.userAgent.match(/ipad|iPod|iphone/i)) {
            var el = $inviteUrl.get(0);
            var editable = el.contentEditable;
            var readOnly = el.readOnly;
            el.contentEditable = true;
            el.readOnly = false;
            var range = document.createRange();
            range.selectNodeContents(el);
            var sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
            el.setSelectionRange(0, 999999);
            el.contentEditable = editable;
            el.readOnly = readOnly;
            document.execCommand('copy');
            $inviteUrl.blur();
        } else {
            $inviteUrl.select();
            document.execCommand("copy");
        }
    }
});

addEvent(event, function(event) {
    if ($inviteUrl.val() && event.target.id == 'invite-url') {
        var $copyLink = $('#copy-link i');
        $copyLink.removeClass('fa-clone');
        $copyLink.addClass('fa-check');
        $('.copy-success').removeClass('hidden');
        setTimeout(function() {
            $copyLink.removeClass('fa-check');
            $copyLink.addClass('fa-clone');
            $('.copy-success').addClass('hidden');
        }, 2000);
    }
});
0
Renga

これが私の解決策です

var codeElement = document.getElementsByClassName("testelm") && document.getElementsByClassName("testelm").length ? document.getElementsByClassName("testelm")[0] : "";
        if (codeElement != "") {
            var e = document.createRange();
            e.selectNodeContents(codeElement);
            var selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange(e);
            document.execCommand("Copy");
            selection.removeAllRanges();
        }
0
Adithya Sai