Cómo copiar al portapapeles en JavaScript con la API del portapapeles

La función copiar/pegar es sin duda una de las funciones más utilizadas en la informática moderna y se refiere al proceso de copiar/transferir texto...

Introducción

La función copiar/pegar es sin duda una de las funciones más utilizadas en la informática moderna y se refiere al proceso de copiar/transferir texto o imágenes de una parte de una aplicación informática a otra. Más recientemente, se ha convertido en una práctica común copiar mediante programación algunos contenidos en el portapapeles de un usuario, para que no tengan que hacerlo.

Por ejemplo, códigos de activación y verificación que aparecen en una página o correo electrónico. Puede copiarlos automáticamente o tener un botón que le permita a alguien copiar el contenido al portapapeles, para que no tengan que copiarlo ellos mismos. Además, los fragmentos de código son un excelente ejemplo de contenido que quizás desee copiar en un portapapeles.

En esta guía, veremos cómo copiar contenido mediante programación al portapapeles utilizando la nueva API de portapapeles de JavaScript.

{.icon aria-hidden=“true”}

Nota: A menos que esté en localhost, la nueva API del portapapeles solo funcionará si su sitio web está alojado en un dominio seguro (HTTPS).

Copiar al Portapapeles en JavaScript

¡Todo el proceso se puede simplificar con un botón (u otro elemento) que activa el código! También puede hacer esto en la carga de la página, pero generalmente se recomienda ser conservador cuando se trata de interactuar automáticamente con el usuario y realizar acciones que afectan su máquina local (como agregar algo al portapapeles):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<textarea id="content"></textarea>
<button onclick="copyToClipboard()">Copy</button>

<script>
  function copyToClipboard() {
    var copyText = document.getElementById("content").value;
    navigator.clipboard.writeText(copyText).then(() => {
        // Alert the user that the action took place.
        // Nobody likes hidden stuff being done under the hood!
        alert("Copied to clipboard");
    });
  }
</script>

Sin embargo, hay más que decir aquí: cómo funciona, las limitaciones, cómo copiar imágenes, etc. En el resto de la guía, cubriremos exactamente esto.

Anteriormente, los desarrolladores de JavaScript confiaban en document.execCommand(). Sin embargo, recientemente se lanzó una API de Portapapeles relativamente nueva para hacer que la transferencia de datos a través de copiar/pegar sea perfecta.

Leer el permiso del navegador

Dependiendo de la acción que esté realizando (leyendo o escribiendo) con la API del Portapapeles, siempre es recomendable verificar el permiso de los navegadores antes de intentar cualquier operación. Para comprobar si tiene acceso de escritura, utilizará navigator.permissions y consultará el permiso clipboard-write:

1
2
3
4
5
navigator.permissions.query({ name: "clipboard-write" }).then((result) => {
  if (result.state == "granted" || result.state == "prompt") {
    alert("Write access ranted!");
  }
});

De manera similar, también puede verificar si tiene acceso de “lectura del portapapeles”:

1
2
3
4
5
navigator.permissions.query({ name: "clipboard-read" }).then((result) => {
  if (result.state == "granted" || result.state == "prompt") {
    alert("Read access ranted!");
  }
});

Copiar texto al portapapeles

Empecemos por copiar el texto en el portapapeles. Hemos visto esto brevemente en el primer ejemplo, y realmente no se vuelve mucho más complejo que eso. Para copiar texto con la nueva API del portapapeles, usamos un método asincrónico writeText() y este método acepta solo un parámetro: el texto para copiar en el portapapeles.

Al ser asíncrono, devuelve una promesa, que se resuelve si el portapapeles se ha actualizado correctamente y se rechaza en caso contrario:

1
2
3
4
5
navigator.clipboard.writeText("TEXT_TO_COPY_TO").then(() => {
  /* Resolved - text copied to clipboard */
},() => {
  /* Rejected - clipboard failed */
});

Leer contenido del portapapeles

Similar a la escritura, también puede leer el contenido de un portapapeles. Esto plantea problemas de privacidad y, por supuesto, debe ser transparente y cuidadoso al usar la función. Es posible que desee encadenar la escritura y la lectura juntas, para asegurarse de que todo lo que lea sea solo lo que ya escribió.

Por ejemplo, un usuario puede abrir un código de verificación en una página, que se copia automáticamente en el portapapeles. Si está seguro de que irán a otra página con esa entrada en el portapapeles, puede leer la entrada y pegarla en otro campo, para, una vez más, ¡ahorrarles un poco de tiempo y esfuerzo!

Usamos el método readText() para leer la última entrada en el portapapeles. Este método también devuelve una promesa que se resuelve si el navegador puede acceder al contenido del portapapeles y se rechaza de lo contrario:

1
2
3
4
5
navigator.clipboard
  .readText()
  .then((copiedText) => {
        // Do something with copied text
   });

A diferencia de escribir en el portapapeles, solicitar leer el contenido del portapapeles del navegador también muestra un aviso único que le pide al usuario que dé su consentimiento, como se muestra en la imagen a continuación:

Browser prompt

Copiar imagen y texto enriquecido al portapapeles

Texto enriquecido hace referencia a contenidos textuales que permiten estilos como - negrita, cursiva y [subrayado]{.subrayado}, así como diferentes familias de fuentes y tamaños de fuente. Al copiar contenido textual, puede estar en formato de texto enriquecido, lo que significa que hay más metadatos con respecto al contenido que solo el texto en sí.

También podemos usar el método write() de la API del portapapeles para copiar datos arbitrarios, como texto enriquecido e imágenes, y esta función acepta solo un parámetro, que es una matriz que contiene los datos que se escribirán en el portapapeles. El método writeText() está especializado en texto sin formato, mientras que write() puede escribir cualquier dato arbitrario.

Por ejemplo, podría obtener una imagen de una URL remota y copiarla en el portapapeles:

1
2
3
4
5
6
7
const copyImage = async () => {
    const response = await fetch("/path/to/image.png");
    const blob = await response.blob();
    await navigator.clipboard.write([
      new ClipboardItem({ "image/png": blob }),
    ]);
  };

El ejemplo anterior también funciona para copiar textos enriquecidos, cuando cambia el tipo del elemento a "text/html":

1
2
3
4
5
6
const copyRichText = async () => {
    const content = document.getElementById("richTextInputId").innerHTML;
    const blob = new Blob([content], { type: "text/html" });
    const richTextInput = new ClipboardItem({ "text/html": blob });
    await navigator.clipboard.write([richTextInput]);
};

Esto supone que el elemento richTextInputId admite texto enriquecido en sí mismo.

Leer imagen y texto enriquecido del portapapeles

La API del portapapeles también proporciona un método read() distinto, que se usa para leer datos arbitrarios en lugar de texto sin formato, y funciona de manera similar a la función anterior readText(), pero puede leer datos arbitrarios. Por ejemplo, para leer los datos de una imagen que se copió previamente en el portapapeles:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<img src="" alt="" id="sample-img" />
<script>
const img = document.getElementById("sample-img");
  navigator.clipboard.read().then((data) => {
  for (let i = 0; i < data.length; i++) {
    if (!data[i].types.includes("image/png")) {
      // Clipboard does not contain image data
    } else {
      data[i].getType("image/png").then((blob) => {
          img.src = URL.createObjectURL(blob);
      });
    }
  }
});
</script>

Conclusión

En esta breve guía, hemos podido cubrir el proceso de copiar texto y otros datos, como imágenes, al portapapeles utilizando la nueva API de Portapapeles. Siempre que esté escribiendo o leyendo desde la máquina local de un usuario, ¡tenga cuidado de ser transparente y seguro sobre el proceso! proceso!