Botón para copiar URL en el portapapeles | Oloblogger Hoy veremos una pequeña utilidad JavaScript para conseguir que al pulsar un determinado enlace (o botón), la dirección de la página que se e...

28 de septiembre de 2016

Botón para copiar URL en el portapapeles

Hoy veremos una pequeña utilidad JavaScript para conseguir que al pulsar un determinado enlace (o botón), la dirección de la página que se esté visitando pase al portapapeles del lector.

Con esto el visitante del sitio tendrá fácil posteriormente con un simple CTRL+V, pegar esa dirección dónde guste. Esto puede servirle para compartir manualmente la dirección de un post que le haya gustado en redes sociales, pasarlo a un bloc de notas, añadirlo a favoritos, etc.

Tras ver el código básico, aplicaremos en él unas pequeñas modificaciones para conseguir algunos efectos adicionales y para finalizar indicaré cómo disponer el código para añadirlo a la colección de botones sociales ligeros de peso que ya explicamos tiempo atrás.



Código básico


El código básico es una función que añade a la página un nuevo elemento input y lo rellena con el dato de la dirección que capta mediante window.location.href. Posteriormente selecciona ese contenido, lo copia al portapapeles y por último elimina el input creado para que no se vea.

Una vez que tenemos montada esa función que he bautizado como getlink(), lo único que resta es crear un botón que ejecute esa función al hacer clic sobre él.

Todo esto junto sería así, aunque si se va a usar con frecuencia lo mejor sería poner la parte JavaScript en plantilla:
<a class="copi" href="javascript:getlink();">Copiar URL</a>

<script>//<![CDATA[
function getlink() {
var aux = document.createElement("input");
aux.setAttribute("value",window.location.href);
document.body.appendChild(aux);
aux.select();
document.execCommand("copy");
document.body.removeChild(aux);
}
//]]></script>

Y el resultado sería este. Si pincháis en ese enlace y luego pegáis en cualquier sitio, os aparecerá la dirección de esta entrada.

Copiar URL


Lo de añadirle una clase (en el ejemplo copi), no es obligatorio, pero si conveniente si luego queremos que ese enlace simple se transforme en un botón añadiéndole CSS.

.copi {
display: block;
width: 120px;
margin: 0 auto;
padding: 10px;
color: #ffffff;
background: #990000;
text-align: center;
}

Copiar URL

Un paso más. Eliminar algunos elementos de la dirección


La estructura de una URL es la siguiente:

[protocolo]://[dominio].[subdominio]/[ruta]/[recurso]?[cadena de búsqueda]#[hash]

http://www.oloblogger.com/2010/02/generar-y-recuperar-cookies.html?m=1#c19290

Como veis, en ella pueden aparecer algunos parámetros que modifican en algo el destino o incluso apuntan a una parte concreta del documento. Para el caso de que no nos interese que esos parámetros se compartan habría que añadir unos split (resaltados) para recortar del dato capturado (URL completa) precisamente la cadena de búsqueda y el hash (en ese mismo orden en el ejemplo).

<a class="copi" href="javascript:getlink();">Copiar URL</a>

<script>//<![CDATA[
function getlink() {
var aux = document.createElement("input");
aux.setAttribute("value",window.location.href.split('?')[0].split('#')[0]);
document.body.appendChild(aux);
aux.select();
document.execCommand("copy");
document.body.removeChild(aux);
}
//]]></script>


Confirmar al usuario que ya tiene el enlace en su portapapeles


Para hacer más amigable el asunto y sobre todo, para que el usuario sepa que la información se ha transferido a su portapapeles ¿qué tal si añadimos un mensaje?

La manera más sencilla es añadir un alert que nos genere una ventana emergente. Lo pondríamos al final del todo añadiendo un mensaje de texto y la dirección que efectivamente se ha copiado:

<a class="copi" href="javascript:getlink();">Copiar y avisar</a>

<script>//<![CDATA[
function getlink() {
var aux = document.createElement("input");
aux.setAttribute("value", window.location.href.split("?")[0].split("#")[0]);
document.body.appendChild(aux);
aux.select();
document.execCommand("copy");
document.body.removeChild(aux);
alert("URL copiada al portapapeles\n\n" + window.location.href.split("?")[0].split("#")[0]);
}
//]]></script>

Copiar y avisar



Toque final. Mensaje personalizado que desaparece pasado un tiempo


Esto ya va de hacer las cosas más monas. Lo anterior hace su función perfectamente pero las ventanas de JavaScript siempre recuerdan a los puñeteros pop-up no deseados, así que veamos como hacer una a nuestro estilo y que además desaparece sola automáticamente tras mostrarse lo suficiente.

Con respecto al anterior código evidentemente eliminamos la línea antes añadida que contiene el alert. De nuevo resalto lo que se ha añadido para este nuevo fin, que no es mas que instrucciones para crear un nuevo nodo con el CSS del mensaje y otro con el aviso propiamente dicho. La última línea sirve para que desaparezca pasados 2000 milisegundos, o sea, 2 segundos.

<a href='javascript:getlink();'>Copiar URL</a>

<script>//<![CDATA[
function getlink() {
var aux = document.createElement("input");
aux.setAttribute("value", window.location.href.split("?")[0].split("#")[0]);
document.body.appendChild(aux);
aux.select();
document.execCommand("copy");
document.body.removeChild(aux);
var css = document.createElement("style");
var estilo = document.createTextNode("#aviso {position:fixed; z-index: 9999999; widht: 120px; top:30%;left:50%;margin-left: -60px;padding: 20px; background: gold;border-radius: 8px;font-size: 14px;font-family: sans-serif;}");
css.appendChild(estilo);
document.head.appendChild(css);
var aviso = document.createElement("div");
aviso.setAttribute("id", "aviso");
var contenido = document.createTextNode("URL copiada");
aviso.appendChild(contenido);
document.body.appendChild(aviso);
window.load = setTimeout("document.body.removeChild(aviso)", 2000);

}
//]]></script>


Copiar, avisar y desaparecer




Opción: Todo el código en el propio botón


Para terminar, si queréis añadir este botón a los de la colección de botones sociales ligeros sin necesidad de poner JavaScript aparte, sino todo dentro del enlace del botón tal y como hacíamos con los otros, esto será lo que tendréis que utilizar... exclusivamente.

Con aviso básico (alert)
<!-- Copiar -->
<div class='copi'>
<a href='javascript:void();' onclick='var a=document.createElement(&quot;input&quot;);a.setAttribute(&quot;value&quot;,window.location.href.split(&quot;?&quot;)[0].split(&quot;#&quot;)[0]),document.body.appendChild(a),a.select(),document.execCommand(&quot;copy&quot;),document.body.removeChild(a);alert(&quot;URL copiada&quot;);'>Copy URL</a>
</div>

Con aviso que desaparece automáticamente
<!-- Copiar -->
<div class='copi'>
<a href='javascript:void();' onclick='var a=document.createElement(&quot;input&quot;);a.setAttribute(&quot;value&quot;,window.location.href.split(&quot;?&quot;)[0].split(&quot;#&quot;)[0]),document.body.appendChild(a),a.select(),document.execCommand(&quot;copy&quot;),document.body.removeChild(a);var c=document.createElement(&quot;style&quot;),e=document.createTextNode(&quot;#av{position:fixed;z-index:999999;width:120px;top:30%;left:50%;margin-left:-60px;padding:20px;background:gold;border-radius:8px;font-size: 14px;font-family:sans-serif;text-align:center;}&quot;);c.appendChild(e),document.head.appendChild(c);var av=document.createElement(&quot;div&quot;);av.setAttribute(&quot;id&quot;,&quot;av&quot;);var c=document.createTextNode(&quot;URL copiada&quot;);av.appendChild(c),document.body.appendChild(av),window.load=setTimeout(&quot;document.body.removeChild(av)&quot;,2e3);'>Copy URL</a>
</div>

Para practicar podéis utilizar este CodePen.



Jorge MG llama mi atención sobre lo inútil del código para algunos navegadores, como por ejemplo Firefox. Bueno, el lo dice más educadamente pero lo cierto es que no sirve para todos los casos.

Con su sugerencia he retocado el código y definitivamente este sería el que habría que usar en lugar del que está bajo el título "Toque final...".

Nótese que el botón-enlace ya no tiene ninguna instrucción JavaScript y será un addEventListener, asociado a un clic sobre el botón (mouseup) el que detectará si se ha pinchado y lanzará la rutina. Esta forma de ordenar el comienzo es la que permite que el resto del código funcione en Firefox y otros.

Además ahora el 'copy' se ejecuta dentro de un try, para así detectar la eventualidad de que el sistema no funcione en el navegador y avise de ello. Lo demás prácticamente lo mismo, pero acortando un poco la inclusión de CSS para el aviso.

<a class='copi' id='getlink' href='javascript:void();'>Copiar URL</a>

<script>//<![CDATA[
var boton = document.getElementById('getlink');
boton.addEventListener('click', function(e) {
if(boton.id == 'getlink'){
var aux = document.createElement('input');
aux.setAttribute('value', window.location.href.split('?')[0].split('#')[0]);
document.body.appendChild(aux);
aux.select();
try {
document.execCommand('copy');
var aviso = document.createElement('div');
aviso.setAttribute('id', 'aviso');
aviso.style.cssText = 'position:fixed; z-index: 9999999; top: 50%;left:50%;margin-left: -70px;padding: 20px; background: gold;border-radius: 8px;font-family: sans-serif;';
aviso.innerHTML = 'URL copiada';
document.body.appendChild(aviso);
document.load = setTimeout('document.body.removeChild(aviso)', 2000);
document.load = setTimeout('boton.id = "getlink"',2500);
boton.id = '';
} catch (e) {
alert('Tu navegador no soporta la función de copiar');
}
document.body.removeChild(aux);
}
});
//]]></script>


Y ahora sí, podéis probar incluso desde Firefox y funcionará bien el botón.

Copiar, avisar y desvanecer
Crossbrowser


Para "todo el código dentro del propio botón", ahora sería exactamente igual que el anterior. Si acaso eliminando los espacios y saltos de línea que no son necesarios para que ocupe menos.

El nuevo Codepen es http://codepen.io/oloman/pen/WGkrWp

¿Vemos otro post al azar por si le encuentras utilidad o quizás prefieres ser más metódico y suscribirte a nuestras entradas por correo? También puedes imprimir este artículo y por supuesto compartirlo en redes sociales si fue de tu agrado.

Compartir
Copy URL

Y muchos más artículos interesantes si nos sigues en...

follow us in feedly

19 comentarios :

  1. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
    Respuestas
    1. Si no me das más pistas no. Yo la veo como está ahora, pero no sé cómo debería estar. No sé qué gadget se te desconfiguró y en qué, ni tampoco sé qué letra te sale mal y cuál debería salir.

      Eliminar
  2. El código que indicas puede fallar en los navegadores que no soporten la función de copiar, así que sería conveniente comprobar si se ha copiado correctamente antes de mostrar la alerta.

    En lugar de:
    document.execCommand("copy");

    podemos escribir:
    var copiado;
    try {
    copiado = document.execCommand("copy");
    } catch(e) {
    copiado = false;
    }
    if (copiado) {
    alert("URL copiada al portapapeles\n\n" + window.location.href.split("?")[0].split("#")[0]);
    } else {
    alert("Tu navegador no soporta la función de copiar");
    }


    De esta forma, avisamos al usuario en caso de fallo, tanto en la función "execCommand" (entraría en el "catch") como en algún error de seguridad ("execCommand" devolvería false).

    Además, Firefox requiere que "execCommand" se ejecute desde un manejador de eventos mediante "addEventListener". Si se ejecuta desde el atributo "onclick" o "href:javascript", como en este caso, falla (devuelve false) y lanza una advertencia en la consola.

    ResponderEliminar
    Respuestas
    1. Muy cierto Jorge. No me di cuenta de esa circunstancia con Firefox ¿Podrías por favor decirme si lo ves mejor así para actualizar la entrada? http://codepen.io/oloman/pen/WGkrWp

      Eliminar
    2. Perfecto, ya funciona en Firefox.
      Y si por algún casual fallase en navegadores antiguos, se avisa del error.

      Eliminar
    3. Muchas gracias. Voy a actualizar

      Eliminar
  3. Hola, muchas gracias por el código pero lo único que no me gusta es cuando uno hace clik dos veces seguidos para copiar al portapapeles en el navegador Google Chrome y Opera y se queda pegado en la pantalla el aviso que dice "Url copiada", me gustaría saber si tienes una solución para que desaparesca el aviso en estos navegadores, te lo agradecería mucho y gracias nuevamente por tu código

    ResponderEliminar
    Respuestas
    1. Pues creo que sí. Añadí un par de líneas al código de la actualización. Prueba ahora y me dices.

      Eliminar
    2. Hola, gracias ahora si quedo perfecto!!

      Eliminar
  4. Hola, en dispositivos móviles no sirve? en mi Chrome de Iphone no copia nada, quedo atento gracias.

    ResponderEliminar
    Respuestas
    1. Hola. Pues pensaba que tendrías razón y que posiblemente no funcionaría en móviles, pero he probado con un Android y sí que va. De ahí tengo que deducir que dónde no funciona es en iPhone, pero eso ya no lo puedo solucionar porque no tengo nada Apple para probar y encontrar la causa del problema :(

      Eliminar
  5. en uno de mis blogs no funciona la ultima.....la antepenultima si.

    ResponderEliminar
  6. en uno de los blogs q iva bien en la 1º paginasolo se ve una entrada en las demas las q marco

    ResponderEliminar
    Respuestas
    1. No entiendo lo que pasa. Mejor me lo indicas con la dirección concreta del sitio dónde no funciona. Especifica QUÉ código no funciona y qué navegador usas.

      Eliminar
  7. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  8. Como hago para crear el boton,, pero no para copiar la direccion url donde se encuentra,, sino otra direccion url.. osea otra pagina distinta.. hay alguna forma??

    ResponderEliminar
  9. Hola, Oloman. Incluí el truco a mi blog. Anteriormente había incluido un código que oculta la fecha de la url y el html, así que el botón copia esa url, y precisamente lo que quería era que copiara la url original como lo hace el botón de copiar enlace predeterminado de blogger, pero ese esta dentro del cuadro de compartir.

    Entonces veo dos maneras cambiar tu código para que copie la url original, lo que no se como hacer. O extraer el de blogger que de hecho también viene con aviso pero que tampoco se como hacer. Ojala andes por acá para que me puedas echar una mano. Saludos.

    ResponderEliminar
    Respuestas
    1. ¡Conseguí lo que quería! Créditos a Mikel Ferreiro por la solución que me a dado en Stackflow.
      https://es.stackoverflow.com/a/252916/122977

      Pueden probar el botón en algunas de las entradas de este blog:
      https://activismoeficazea.blogspot.com

      Eliminar