Copy the contents of an element to the clipboard using JavaScript

25

How can I copy the contents of a div (or any element) to the clipboard using JavaScript / jQuery only without using Flash?

For example, if I have this code:

<p id="mi_parrafo">
  Texto que quiero copiar
</p>
<button>Copiar al portapapeles</button>

What should I do so that, after pressing the button, when I press Ctr + V the content is pasted inside the tag marked%% of%?

    
asked by Alvaro Montoro 07.12.2015 в 17:25
source

2 answers

26

There is at least one way to achieve this without using Flash: using the copy command % This command will copy to the clipboard the text that is selected on the page at the moment of execution.

So you can create a small function that:

  • Create a temporary text field (which will not be visible).
  • Assign the content of the element to be copied to the value of the text field.
  • Select the content of the text field.
  • Execute the copy: document.execCommand("copy") command.
  • Destroy / Delete the temporary field.
  • Then the content of the selected element will be in the clipboard. The code would be like this:

    function copiarAlPortapapeles(id_elemento) {
    
      // Crea un campo de texto "oculto"
      var aux = document.createElement("input");
    
      // Asigna el contenido del elemento especificado al valor del campo
      aux.setAttribute("value", document.getElementById(id_elemento).innerHTML);
    
      // Añade el campo a la página
      document.body.appendChild(aux);
    
      // Selecciona el contenido del campo
      aux.select();
    
      // Copia el texto seleccionado
      document.execCommand("copy");
    
      // Elimina el campo de la página
      document.body.removeChild(aux);
    
    }
    

    The main problem with this solution is that not all browsers support this command , although it can be used in the main ones from:

    • Chrome 43
    • Internet Explorer 10
    • Firefox 41

    A demo of the code in operation:

    function copiarAlPortapapeles(id_elemento) {
      var aux = document.createElement("input");
      aux.setAttribute("value", document.getElementById(id_elemento).innerHTML);
      document.body.appendChild(aux);
      aux.select();
      document.execCommand("copy");
      document.body.removeChild(aux);
    }
    <p id="p1">P1: Soy el primer párrafo</p>
    <p id="p2">P2: Soy el segundo párrafo</p>
    <button onclick="copiarAlPortapapeles('p1')">Copiar P1</button>
    <button onclick="copiarAlPortapapeles('p2')">Copiar P2</button>
    <br/><br/>
    <input type="text" placeholder="Pega aquí para probar" />

    You can also create an equivalent version using jQuery:

    function copyToClipboard(elemento) {
      var $temp = $("<input>")
      $("body").append($temp);
      $temp.val($(elemento).text()).select();
      document.execCommand("copy");
      $temp.remove();
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <p id="p1">P1: Soy el primer párrafo</p>
    <p id="p2">P2: Soy el segundo párrafo</p>
    <button onclick="copyToClipboard('#p1')">Copiar P1</button>
    <button onclick="copyToClipboard('#p2')">Copiar P2</button>
    <br/>
    <br/>
    <input type="text" placeholder="Pega aquí para probar" />

    That works in a similar way to the previous example, although some errors have been reported in Safari for Mac and Chrome 64-bit (see the comments in link of the original source for more data).

    Source: original response on the StackOverflow site .

    EXTENSION: COPY BY MAINTAINING THE STYLES

    In another question in StackOverflow en Español , a user commented that text format / styles were not copied . This is because the code above uses input text to copy the content of the element, so the HTML code is "lost" (it is interpreted literally instead of as HTML). If instead of using a input we use a div editable, the format is not lost and can be copied / pasted with styles:

    function ejecutar(idelemento){
      var aux = document.createElement("div");
      aux.setAttribute("contentEditable", true);
      aux.innerHTML = document.getElementById(idelemento).innerHTML;
      aux.setAttribute("onfocus", "document.execCommand('selectAll',false,null)"); 
      document.body.appendChild(aux);
      aux.focus();
      document.execCommand("copy");
      document.body.removeChild(aux);
    }
    #destino {
      width:400px;
      height:100px;
      border:1px solid #ccc;
    }
    <p id="demo"><b>Caso con formato.</b></p>
    <button onclick="ejecutar('demo')">Copiar</button> 
    <br/>
    <div id="destino" contentEditable="true">
    </div>
        
    answered by 23.05.2017 / 14:39
    source
    11

    Only to complement you could take a look at the library clipboard.js , which as @ Alvaro mentions makes use of of execCommand so according to the library page it says it works in Chrome 42+, Firefox 41+, IE 9+ and Opera 29 +.

    For Safari it does not work, but when you try it on an iPad you select the text of input at the same time that it shows you the native option to copy it.

    The difference is in the ease of use , because with little time and effort you manage to copy the content you want, the following code copies the content of a input , but you can also copy / cut the content of another element ( button, div, etc ).

    var clipboard = new Clipboard('.btn');
    <script src="https://cdn.rawgit.com/zenorocha/clipboard.js/v1.5.3/dist/clipboard.min.js"></script>
    <!-- Objetivo -->
    <input id="foo" value="Texto a copiar">
    
    <!-- Disparador -->
    <button class="btn" data-clipboard-target="#foo">
      Copiar al portapapeles
    </button>
        
    answered by 07.12.2015 в 19:38