Cómo agregar un botón Copiar al portapapeles usando JavaScript

Cómo crear una función que recibe una cadena de texto para copiar en el portapapeles de los usuarios cuando se le llama.

Primeros pasos

Para este tutorial, vamos a utilizar el marco JavaScript de pila completa de CheatCode, Joystick. Joystick reúne un marco de interfaz de usuario de front-end con un back-end de Node.js para crear aplicaciones.

Para comenzar, querremos instalar Joystick a través de NPM. Asegúrese de estar usando Node.js 16+ antes de instalar para garantizar la compatibilidad (lea este tutorial primero si necesita aprender a instalar Node.js o ejecutar varias versiones en su computadora):

Terminal

npm i -g @joystick.js/cli

Esto instalará Joystick globalmente en su computadora. Una vez instalado, vamos a crear un nuevo proyecto:

Terminal

joystick create app

Después de unos segundos, verá un mensaje desconectado de cd en su nuevo proyecto y ejecute joystick start :

Terminal

cd app && joystick start

Después de esto, su aplicación debería estar ejecutándose y estamos listos para comenzar.

Agregar un componente Joystick

En la aplicación que acabamos de crear, se creó para nosotros un componente de página de ejemplo que ya está conectado a nuestro enrutador en /ui/pages/index/index.js . Para comenzar, abriremos este archivo y reemplazaremos su contenido con un componente esqueleto en el que construiremos nuestra funcionalidad de copia al portapapeles:

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  render: () => {
    return `
      <div>
      </div>
    `;
  },
});

export default Index;

Aquí, comenzamos importando el ui objeto del @joystick.js/ui paquete:la parte del marco de la interfaz de usuario del marco Joystick de CheatCode. A continuación, creamos una variable const Index y asignarlo a una llamada a ui.component() . Este método crea un nuevo componente Joystick para nosotros utilizando las opciones que le pasamos como objeto.

En ese objeto, hemos agregado una sola propiedad render que se asigna a una función que devuelve el HTML que queremos mostrar en pantalla cuando cargamos este componente en nuestra aplicación. Por ahora, solo estamos devolviendo una cadena con un <div></div> vacío etiqueta.

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  css: `
    div {
      display: flex;
    }

    div button {
      margin-left: 10px;
    }
  `,
  render: () => {
    return `
      <div>
        <input type="text" />
        <button class="copy">Copy</button>
      </div>
    `;
  },
});

export default Index;

Desarrollando el HTML, a continuación, queremos agregar un <input /> etiqueta con un type de text y un botón con un class de copy . Nuestro objetivo será tomar lo que escribamos en la entrada y cuando hagamos clic en el botón "Copiar", copiarlo en el portapapeles. Justo encima de esto, agregamos un CSS simple para limpiar la visualización de nuestra entrada y el botón para que queden uno al lado del otro en la pantalla.

Agregar una copia al portapapeles

A continuación, debemos conectar el botón que manejará la copia de nuestro texto en el portapapeles.

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  events: {
    'click .copy': (event, component) => {
      const input = component.DOMNode.querySelector('input');
      component.methods.copyToClipboard(input.value);
    },
  },
  css: `...`,
  render: () => {
    return `
      <div>
        <input type="text" />
        <button class="copy">Copy</button>
      </div>
    `;
  },
});

export default Index;

Para manejar el evento de copia, necesitamos agregar un detector de eventos en nuestro botón para que cuando se haga clic en él, podamos obtener el valor de entrada actual y luego transferirlo a nuestra función de copia.

Aquí, estamos agregando una opción a nuestro componente events que se asigna a un objeto donde cada nombre de propiedad es la combinación de un tipo de evento DOM que queremos escuchar y el elemento que queremos escuchar en <event> <element> . A esa propiedad, le asignamos una función que queremos que Joystick llame cada vez que se detecte ese evento en ese elemento.

Para nuestras necesidades, queremos obtener el valor actual de <input /> etiqueta que estamos representando en nuestro HTML. Para hacerlo, anticipamos que Joystick nos pasará el evento DOM sin procesar que está teniendo lugar como primer argumento de nuestra función y como segundo argumento, la instancia del componente actual.

En esa instancia, Joystick nos da acceso al componente actual tal como se representa en el navegador en component.DOMNode . Este es un objeto de nodo DOM de JavaScript simple, lo que significa que podemos realizar cualquier método estándar de JavaScript en él. Aquí, estamos llamando a querySelector() para decir "dentro de este elemento—component.DOMNode —busca un elemento llamado input ."

Con ese elemento, a continuación, llamamos a component.methods.copyToClipboard() pasando el value propiedad de nuestro input (esto contendrá el valor de texto actualmente en la entrada).

Nuestro último paso es conectar ese methods.copyToClipboard() función para hacer que esto funcione.

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  methods: {
    copyToClipboard: (text = '') => {
      const textarea = document.createElement("textarea");
      textarea.value = text;
      document.body.appendChild(textarea);
      textarea.select();
      document.execCommand("copy");
      document.body.removeChild(textarea);
    },
  },
  events: {
    'click .copy': (event, component) => {
      const input = component.DOMNode.querySelector('input');
      component.methods.copyToClipboard(input.value);
    },
  },
  css: `...`,
  render: () => {
    return `
      <div>
        <input type="text" />
        <button class="copy">Copy</button>
      </div>
    `;
  },
});

export default Index;

Esta es la parte importante. En un componente Joystick, podemos definir funciones arbitrarias que queremos disponibles bajo el methods objeto. Aquí, hemos agregado copyToClipboard() como uno de esos métodos ("método" es solo el nombre propio para una función definida en un objeto en JavaScript), tomando una cadena de text (aquí, el valor que acabamos de extraer de nuestra entrada, pero potencialmente cualquier cadena que queramos copiar al portapapeles).

Debido a que JavaScript carece de una característica nativa de "copiar al portapapeles", para que esto funcione, necesitamos hacer un pequeño truco.

Dentro de esta función, primero queremos crear dinámicamente un <textarea></textarea> elemento en la memoria. A continuación, asignamos el valor de ese textarea elemento al text pasamos a copyToClipboard() . Una vez que esto está configurado, agregamos dinámicamente el textarea al <body></body> etiqueta de nuestro navegador y luego llamar inmediatamente al .select() método en él.

A continuación, usamos el document.execCommand() función pasando la cadena "copy" para decirle al navegador que ejecute el comando de copia que copiará lo que esté actualmente seleccionado en el navegador al portapapeles. Finalmente, llamamos a document.body.removeChild(textarea) para eliminar el <textarea></textarea> acabamos de inyectar.

¡Eso es todo! Ahora, si abrimos nuestra aplicación en el navegador en http://localhost:2600 , cuando hacemos clic en nuestro botón, el valor actual de nuestra entrada pasará a methods.copyToClipboard() y se copiarán automáticamente en el portapapeles.

Terminando

En este tutorial, aprendimos cómo crear una función simple para copiar texto al portapapeles. Aprendimos a conectar un componente de interfaz de usuario simple usando Joystick y luego, al hacer clic en un botón, copiar el texto actual de una entrada al portapapeles.