Sugerencia rápida:acceder al portapapeles con JavaScript

En este artículo, le mostraremos cómo usar fragmentos simples de JavaScript para:

  1. Agregue texto al portapapeles con la acción del usuario, como presionar un botón.
  2. Modificar el contenido del portapapeles cuando un usuario copia algo.

¡Las API que usaremos no requieren bibliotecas externas y tienen una compatibilidad de navegador casi perfecta!

Copiar al hacer clic

Una característica de accesibilidad increíble que puede agregar a su sitio web es la capacidad de copiar cadenas directamente presionando un botón. Esta interacción se puede aplicar para capturar rápidamente URL, cadenas largas como claves SSH, comandos de terminal, colores hexadecimales o cualquier otro dato que se copie y pegue con frecuencia.

Para que esto suceda, necesitaremos usar un método JavaScript genial llamado execCommand() . Nos permite invocar una serie de eventos diferentes que manipulan el contenido editable, como poner el texto en negrita/cursiva, deshacer/rehacer y también copiar/cortar/pegar.

document.execCommand('copy');

Esto funciona exactamente como presionar CTRL/Cmd+C en su teclado, por lo que para copiar cualquier texto, primero debemos tenerlo seleccionado. Esto es posible en JavaScript gracias a la API de selección, que nos permite realizar mediante programación una selección de texto de cualquier elemento HTML de la página.

var button = document.getElementById("copy-button"),
    contentHolder = document.getElementById("content-holder");

button.addEventListener("click", function() {

    // We will need a range object and a selection.
    var range = document.createRange(),
        selection = window.getSelection();

    // Clear selection from any previous data.
    selection.removeAllRanges();

    // Make the range select the entire content of the contentHolder paragraph.
    range.selectNodeContents(contentHolder);

    // Add that range to the selection.
    selection.addRange(range);

    // Copy the selection to clipboard.
    document.execCommand('copy');

    // Clear selection if you want to.
    selection.removeAllRanges();

}, false);

Para ver el ejemplo en acción, consulta el editor a continuación:

var button = document.getElementById("copy-button"),
    contentHolder = document.getElementById("content-holder");

button.addEventListener("click", function() {

    // We will need a range object and a selection.
    var range = document.createRange(),
        selection = window.getSelection();

    // Clear selection from any previous data.
    selection.removeAllRanges();

    // Make the range select the entire content of the contentHolder paragraph.
    range.selectNodeContents(contentHolder);

    // Add that range to the selection.
    selection.addRange(range);

    // Copy the selection to clipboard.
    document.execCommand('copy');

    // Clear selection if you want to.
    selection.removeAllRanges();

}, false);
<p id="content-holder">This text will be inserted into the clipboard.</p>

<button id="copy-button">Copy Text</button>

<textarea placeholder="Paste here"></textarea>
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body{
    padding: 20px;
    font: normal 16px sans-serif;
    color: #555;
}

p{
    margin-bottom: 20px;
}

button{
    padding: 8px 12px;
    margin-bottom: 20px;
}

textarea {
    display: block;
    padding: 10px;
    width: 400px;
    height: 120px;
}

En el ejemplo anterior, el contenido que queremos copiar simplemente se almacena en un párrafo. Si el texto que necesita no está en la página, primero deberá escribirlo en un elemento oculto fuera de la pantalla.

Modificar texto copiado

Aquí le mostraremos cómo manipular el contenido en el portapapeles después de haberlo copiado. Esto puede ser muy útil para escapar código, formatear números y fechas, o para otras transformaciones de texto como mayúsculas, minúsculas, etc.

JavaScript nos proporciona copy() y paste() eventos, pero están diseñados de tal manera que el contenido almacenado en el portapapeles es seguro:

  • En la copia controlador de eventos, no podemos leer lo que está almacenado en el portapapeles, ya que puede haber información personal a la que no deberíamos tener acceso. Sin embargo, podemos sobrescribir los datos del portapapeles.
  • En la pega caso de que sea lo contrario:podemos leer los datos, pero no podemos cambiarlos.

Como queremos leer y escribir al mismo tiempo, necesitaremos usar la API de selección una vez más. Aquí está la solución:

document.addEventListener('copy', function(e){

    // We need to prevent the default copy functionality,
    // otherwise it would just copy the selection as usual.
    e.preventDefault();

    // The copy event doesn't give us access to the clipboard data,
    // so we need to get the user selection via the Selection API.
    var selection = window.getSelection().toString();

    // Transform the selection in any way we want.
    // In this example we will escape HTML code.
    var escaped = escapeHTML(selection);

    // Place the transformed text in the clipboard. 
    e.clipboardData.setData('text/plain', escaped);

});

Puedes probar el código en el editor a continuación:

document.addEventListener('copy', function(e){

    // We need to prevent the default copy functionality,
    // otherwise it would just copy the selection as usual.
    e.preventDefault();

    // The copy event doesn't give us access to the clipboard data,
    // so we need to get the user selection via the Selection API.
    var selection = window.getSelection().toString();

    // Transform the selection in any way we want.
    var escaped = escapeHtml(selection);

    // Place the transformed text in the clipboard. 
    e.clipboardData.setData('text/plain', escaped);

});

// Primitive HTML escape function.
function escapeHtml(unsafe) {
    return unsafe
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
 }

<p class="copy-text">Copy and paste any of the HTML code below to escape it.</p>

<pre><code>
&lt;div class=&quot;container&quot;&gt;

    &lt;div class=&quot;starter-template&quot;&gt;
        &lt;h1&gt;Lorem Ipsum&lt;/h1&gt;
        &lt;p class=&quot;lead&quot;&gt;Lorem ipsum dolor sit amet.&lt;/p&gt;
    &lt;/div&gt;

&lt;/div&gt;
</code></pre>

<textarea class="paste-text" placeholder="Paste here"></textarea>
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body{
    padding: 20px;
    font: normal 16px sans-serif;
    color: #555;
}

pre{
    font-size: 14px;
    margin-bottom: 20px;
}

textarea {
    padding: 10px;
    width: 500px;
    height: 170px;
}

Lecturas adicionales

En este consejo rápido, le presentamos dos fragmentos útiles para trabajar con el portapapeles en JavaScript puro y simple. Utilizamos un montón de API nativas modernas, por lo que aquí están nuevamente si desea leer más sobre ellas:

  • execCommand:ejecuta acciones como copiar, pegar, cortar, negrita, cursiva, subrayar, eliminar y muchas otras. - MDN, ¿Puedo usar
  • API de selección:permite a los desarrolladores realizar una selección de rango de cualquier texto de la página. - MDN, ¿Puedo usar
  • Evento de copia de JavaScript:un evento que se activa cuando los usuarios presionan CTRL/Cmd+C o eligen "copiar" en el menú contextual. - MDN, ¿Puedo usar

Además, si necesita más control sobre los eventos de copiar/pegar/cortar, puede usar una biblioteca como clipobard.js. Tiene muchas funciones y proporciona una API limpia y agradable para administrar el portapapeles.

¡Esperamos que hayas disfrutado este artículo! No dude en hacer preguntas o dejar sugerencias en la sección de comentarios a continuación :)