Cómo implementar un menú de compartir inline

En este tutorial, aprenderemos a crear lo que hemos denominado como "menú de compartir inline". Esta interfaz funciona haciendo saltar un menú que permite a los visitantes compartir la página, citando el texto resaltado. Es posible que hayas visto un control similar en ciertos sitios webs famosos como Medium.

Antes de empezar a desarrollar nuestro menú de compartir, examinaremos cómo está implementado el menú de compartir de Medium. Este es un paso muy útil que nos proporcionará la información técnica que necesitamos. ¿Estás preparado? ¡Pues vamos allá!

Examinando la interfaz de Medium

En la siguiente imagen podemos ver que el menú de compartir aparece en el centro del texto seleccionado, independientemente de su longitud. Es decir, dará lo mismo si seleccionamos una sola palabra, una frase o todo el párrafo.

Si miramos su código con el Inspeccionador, veremos que la posición del menú de compartir viene dada por las propiedades top y left de los estilos proporcionados en el propio elemento. Podemos ver también que el botón de compartir cuenta con una clase modifier highlightMenu—active, que lo hace visible.

En la pestaña de estilos, podemos que su posición inicial se define vía CSS con la propiedad position:absolute, la propiedad z-index se utiliza para situarse encima de todos los elementos de la página y la con la propiedad visibility ponemos los botones ocultos por defecto.

Resumiendo, lo que necesitamos hacer es:

  • Obtener la longitud del área seleccionada para poder determinar el punto central.
  • Crear un modifier para mostrar el elemento.
  • Establecer la posición del menú de compartir con la propiedad top e left añadida a través de estilos inline.

Desarrollando el menú de compartir

En este ejemplo vamos a incluir los botones de Facebook y de Twitter dentro del menú de compartir. Mostraremos el icono de Facebook y Twitter con unos SVG dentro de un botón junto a un par de elementos div. Además, como puedes ver en el código de abajo, insertaremos un spam para crear el triángulo de la parte inferior del menú.

<div class="sharing">
    <div class="sharing__buttons">
        <button id="share" title="Share">
            <svg class="icon icon--facebook" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512; width: 24px; height: 24px" xml:space="preserve"><g></g><g><g><path d="M426.8,64H85.2C73.5,64,64,73.5,64,85.2l0,341.6c0,11.7,9.5,21.2,21.2,21.2H256V296h-45.9v-56H256v-41.4 c0-49.6,34.4-76.6,78.7-76.6c21.2,0,44,1.6,49.3,2.3v51.8l-35.3,0c-24.1,0-28.7,11.4-28.7,28.2V240h57.4l-7.5,56H320v152h106.8 c11.7,0,21.2-9.5,21.2-21.2V85.2C448,73.5,438.5,64,426.8,64z"/></g></g></svg>
        </button>
        <button id="tweet" title="Tweet">
            <svg class='icon icon--twitter' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 512 512' style='enable-background:new 0 0 512 512; width: 24px; height: 24px' xml:space='preserve'><path d='M492,109.5c-17.4,7.7-36,12.9-55.6,15.3c20-12,35.4-31,42.6-53.6c-18.7,11.1-39.4,19.2-61.5,23.5
                C399.8,75.8,374.6,64,346.8,64c-53.5,0-96.8,43.4-96.8,96.9c0,7.6,0.8,15,2.5,22.1c-80.5-4-151.9-42.6-199.6-101.3
                c-8.3,14.3-13.1,31-13.1,48.7c0,33.6,17.2,63.3,43.2,80.7C67,210.7,52,206.3,39,199c0,0.4,0,0.8,0,1.2c0,47,33.4,86.1,77.7,95c-8.1,2.2-16.7,3.4-25.5,3.4c-6.2,0-12.3-0.6-18.2-1.8c12.3,38.5,48.1,66.5,90.5,67.3c-33.1,26-74.9,41.5-120.3,41.5
                c-7.8,0-15.5-0.5-23.1-1.4C62.8,432,113.7,448,168.3,448C346.6,448,444,300.3,444,172.2c0-4.2-0.1-8.4-0.3-12.5
                C462.6,146,479,129,492,109.5z'/>
            </svg>
        </button>
    </div>
    <span class="sharing__triangle"></span>
</div>

No existe una regla definitiva a la hora de escoger los colores y la forma del menú. Siéntete libre a la hora de diseñar tu menú para que coincida con el diseño de tu sitio web. Vale la pena prestar atención al tamaño del botón, es decir, a su altura y ancho. Nuestro menú de compartir tendrá 84px de ancho y 40px de alto. Utilizaremos estos dos valores para situar el menú de compartir en el centro del área seleccionada más tarde.

Estos son los estilos que definirán la posición y la visibilidad de nuestro menú.

.sharing {
    position: absolute;
    visibility: hidden;
    top: 0;
    left: 0;
    z-index: 500;
}

Y poir último, la clase para cuando queramos que nuestro menú se haga visible.

.sharing--shown {
    visibility: visible;
}

Haciendo funcional el menú

En este punto, nuestro menú de compartir inline no debería verse en la página. Además, cuando hagamos clic en el botón de Facebook y Twitter, la ventana de compartir no aparecerá en ninguna parte. En esta sección, escribiremos el JavaScript para que nuestros botones funcionen. Para ello comenzamos con la función getHighlight().

function getHighlight() {
 
    var selection = window.getSelection(); // 1.
 
    var object = {
        parent : null,
        text   : '',
        rect   : null
    };
 
    // If selection is not empty.
    if ( selection.rangeCount > 0 ) {
        object = {
            text   : selection.toString().trim(), // get the text.
            parent : selection.anchorNode.parentNode, // get the element wrapping the text.
            rect   : selection.getRangeAt(0).getBoundingClientRect() // get the bounding box.
        };
    }
 
    return object; // 2.
}

Esta función:

  • Obtendrá el área seleccionada usando la función JavaScript getSelection().
  • Devolverá un objeto que contendrá el texto seleccionado, el elemento que envuelve al texto y el objeto Rectangle del área seleccionada que nos proporciona información sobre el tamaño, así como su posición, top, bottom, left y right, dentro de la página.

Nuestra siguiente función se llama showMenu(). Como su nombre lo indica, esta función mostrará el menú de compartir.

var sharing = document.querySelector( '.sharing' );
 
function showMenu() {
 
    // 1.
    var highlight = getHighlight();
 
    // 2.
    if ( highlight.text === '' ) {
 
        sharing.setAttribute( 'class', 'sharing' );
        sharing.style.left = 0;
        sharing.style.top  = 0;
 
        return;
    }
 
    // 3.
    /**
     * Only show the sharing button if the selected is a paragraph.
     */
    if ( highlight.parent.nodeName !== 'P' ) {
        return;
    }
 
    // 4.
    var width = ( highlight.rect.width / 2 ) - 42;
    /**
     * The "42" is acquired from our sharing buttons width devided by 2.
     */
 
    sharing.setAttribute( 'class', 'sharing sharing--shown' );
    sharing.style.left = ( highlight.rect.left + width ) + 'px';
    sharing.style.top  = ( highlight.rect.top - 40 ) + 'px';
    /**
     * "40" is the height of our sharing buttons.
     * Herein, we lift it up above the higlighted area top position.
     */
}

El código de esta función hará lo siguiente:

  • Obtener el Object de la función getHighlighted ().
  • Ocultar y definir el menú de compartir a su posición inicial cuando el área resaltada esté vacía, es decir, no contiene texto.
  • Evitar que los botones aparezcan si el texto resaltado no está dentro de un párrafo.
  • Por último, define la posición top y left, y añade la clase sharing--shown para que los botones sean visibles.

Suponiendo que la mayoría de los usuarios utilizan el ratón para seleccionar el contenido de la web, tendremos que vincular esta función al evento mouseup. Los dispositivos móviles suelen tener sus propios menús contextuales en cuanto a selección de texto, por lo que nos centraremos en la web para este tutorial.

Retardamos la ejecución en 100ms utilizando la función setTiemOut(), para asegurarnos que el contenido está seleccionado correctamente.

document.body.addEventListener( 'mouseup', function() {
     setTimeout( showMenu, 100 );
} );

Nuestra última función, openShareWindow(), abre la ventana de compartir cuando se hace clic en los botones del menú. En este tutorial, la utilizaremos principalmente para abrir la ventana de compartir de Twitter, ya que Facebook cuenta con su propio SDK de Javascript.

function openShareWindow( url, w, h ) {
 
    var screenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
    var screenTop = window.screenTop !== undefined ? window.screenTop : screen.top;
    var width = window.innerWidth ? window.innerWidth : doc.documentElement.clientWidth ? doc.documentElement.clientWidth : screen.width;
    var height = window.innerHeight ? window.innerHeight : doc.documentElement.clientHeight ? doc.documentElement.clientHeight : screen.height;
 
    var left = ( ( width / 2 ) - ( w / 2 ) ) + screenLeft;
    var top = ( ( height / 2 ) - ( h / 2 ) ) + screenTop;
 
    var newWin = window.open( url, "", "scrollbars=no,width=" + w + ",height=" + h + ",top=" + top + ",left=" + left );
 
    if ( newWin ) {
        newWin.focus();
    }
}

A continuación, enlazamos los botones de compartir al evento click y adjuntamos una función que abrirá la ventana de compartir.

// Facebook.
document.getElementById( 'share' ).addEventListener( 'click', function() {
 
    var highlight = getHighlight();
 
    if ( highlight.text !== '' && highlight.parent.nodeName === 'P' ) {
        FB.ui({
            method : 'share',
            mobile_iframe: true,
            href   : 'http://programacion.net',
            quote  : highlight.text // pass the text as Quote
        });
    }
 
    event.preventDefault();
} );

Para el botón de, utilizaremos el SDK de Facebook. El SDK nos permite pasarle el texto que queremos compartir mediante el parámetro quote.

Por el contrario, Twitter no cuenta con un SDK Javascript para esto. Por lo que utilizaremos nuestra función openShareWindow(), y le pasamos una URL formateada indicando también el tamaño de la ventana.

document.getElementById( 'tweet' ).addEventListener( 'click', function() {
 
    var highlight = getHighlight();
 
    if ( highlight.text !== '' && highlight.parent.nodeName === 'P' ) {
 
        var docURL = encodeURIComponent( 'http://bitly.com/2aiHmCs' );
        var tweetText = encodeURIComponent( highlight.text );
        var tweetURL = 'https://twitter.com/intent/tweet?via=wdtuts&url=' + docURL + '&text=' + tweetText;
 
        openShareWindow( tweetURL, 600, 420 );
    }
 
    event.preventDefault();
} );

Fuente: Louie R.

Guardar

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
SIGUIENTE ARTÍCULO