27/02/2024
Compartilhar conteúdo nas redes sociais é essencial para aumentar a visibilidade de um site. Para programadores iniciantes, a implementação dessas funcionalidades pode parecer complexa.
Este artigo introduz uma maneira simples de adicionar ícones de compartilhamento social ao seu site, usando componentes web personalizados. Mesmo sem experiência prévia, você será capaz de seguir os passos e melhorar a interatividade do seu projeto.
A seguir, temos o código do componente social-icons
, que você pode adicionar diretamente ao seu projeto. Esse componente permite que os visitantes do seu site compartilhem conteúdo em diversas redes sociais com apenas um clique.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<social-icons icons="whatsapp facebook twitter linkedin pinterest" text="Veja este site"></social-icons>
<script>
class SocialIcons extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
}
static get observedAttributes() {
return ['icons', 'text', 'url'];
}
attributeChangedCallback() {
this.render();
}
getShareLink(network, url, text) {
switch (network) {
case 'facebook':
return `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`;
case 'whatsapp':
return `https://api.whatsapp.com/send?text=${text ? encodeURIComponent(text) + '%20' : ''}${encodeURIComponent(url)}`;
case 'twitter':
return `https://twitter.com/intent/tweet?${text ? 'text=' + encodeURIComponent(text) + '&' : ''}url=${encodeURIComponent(url)}`;
case 'linkedin':
return `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`;
case 'pinterest':
return `https://pinterest.com/pin/create/button/?url=${encodeURIComponent(url)}`;
default:
return '';
}
}
render() {
const iconsAttr = this.getAttribute('icons');
const icons = (!iconsAttr || iconsAttr === 'auto') ? 'whatsapp facebook twitter linkedin pinterest' : iconsAttr;
const text = this.getAttribute('text') || '';
const url = this.getAttribute('url') || location.href;
this.shadowRoot.innerHTML = `
<style>
:host {
display: inline-flex;
flex-direction: row;
gap: 4px;
}
a {
width: 48px;
height: 48px;
background-size: cover;
display: inline-block;
transition: scale 0.3s ease;
}
a:hover {
scale: 1.2;
}
/* Insira aqui os estilos específicos de ícones baseados em classes */
.facebook { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PHBhdGggZD0iTTQyIDM3YTUgNSAwIDAgMS01IDVIMTFhNSA1IDAgMCAxLTUtNVYxMWE1IDUgMCAwIDEgNS01aDI2YTUgNSAwIDAgMSA1IDV2MjZ6IiBmaWxsPSIjM0Y1MUI1Ii8+PHBhdGggZD0iTTM0LjM2OCAyNUgzMXYxM2gtNVYyNWgtM3YtNGgzdi0yLjQxYy4wMDItMy41MDggMS40NTktNS41OSA1LjU5Mi01LjU5SDM1djRoLTIuMjg3QzMxLjEwNCAxNyAzMSAxNy42IDMxIDE4LjcyM1YyMWg0bC0uNjMyIDR6IiBmaWxsPSIjRkZGIi8+PC9zdmc+'); }
.pinterest { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNDggNDgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iMjQiIGN5PSIyNCIgZmlsbD0iI2U2MDAyMyIgcj0iMjAiLz48cGF0aCBkPSJtMjQuNDQ0IDExLjQxNmMtOC42MzIgMC0xMy4yMTUgNS43OTUtMTMuMjE1IDEyLjEwMyAwIDIuOTM0IDEuNTYxIDYuNTg2IDQuMDYgNy43NDkuMzc4LjE3Ni41ODEuMS42NjgtLjI2Ny4wNjctLjI3OS40MDQtMS42MzcuNTU1LTIuMjY5LjA0OS0uMjAxLjAyNS0uMzc0LS4xMzgtLjU3My0uODI3LTEuMDAzLTEuNDg5LTIuODQ2LTEuNDg5LTQuNTY0IDAtNC40MTIgMy4zNC04LjY4IDkuMDMtOC42OCA0LjkxMyAwIDguMzUzIDMuMzQ4IDguMzUzIDguMTM3IDAgNS40MS0yLjczMiA5LjE1OC02LjI4NiA5LjE1OC0xLjk2NCAwLTMuNDMzLTEuNjI0LTIuOTYyLTMuNjE1LjU2NS0yLjM3NyAxLjY1Ny00Ljk0MiAxLjY1Ny02LjY1OSAwLTEuNTM1LS44MjMtMi44MTctMi41My0yLjgxNy0yLjAwNyAwLTMuNjE4IDIuMDc2LTMuNjE4IDQuODU3IDAgMS43Ny41OTggMi45NjkuNTk4IDIuOTY5cy0xLjk4MiA4LjM4MS0yLjM0NSA5Ljk0MWMtLjQwMiAxLjcyMi0uMjQ2IDQuMTQyLS4wNzIgNS43MjMuNDUxLjE3Ny45MDMuMzU0IDEuMzY5LjQ5OS44MTctMS4zMjggMi4wMzUtMy41MDYgMi40ODYtNS4yNDMuMjQ0LS45MzYgMS4yNDctNC43NTQgMS4yNDctNC43NTQuNjUyIDEuMjQ0IDIuNTU2IDIuMjk3IDQuNTgzIDIuMjk3IDYuMDMyIDAgMTAuMzc5LTUuNTQ3IDEwLjM3OS0xMi40NCAwLTYuNjA5LTUuMzkyLTExLjU1Mi0xMi4zMy0xMS41NTJ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+'); }
.whatsapp { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHZpZXdCb3g9IjAgMCA0OCA0OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNC44NjggNDMuMzAzIDIuNjk0LTkuODM1YTE4Ljk0MSAxOC45NDEgMCAwIDEgLTIuNTM1LTkuNDg5Yy4wMDUtMTAuNDY1IDguNTIxLTE4Ljk3OSAxOC45ODctMTguOTc5YTE4Ljg2NyAxOC44NjcgMCAwIDEgMTMuNDMgNS41NjYgMTguODY2IDE4Ljg2NiAwIDAgMSA1LjU1NiAxMy40MjhjLS4wMDQgMTAuNDY1LTguNTIyIDE4Ljk4LTE4Ljk4NiAxOC45OC0uMDAxIDAgMCAwIDAgMGgtLjAwOGExOC45NjUgMTguOTY1IDAgMCAxIC05LjA3My0yLjMxMXoiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJtNC44NjggNDMuODAzYS40OTkuNDk5IDAgMCAxIC0uNDgyLS42MzFsMi42MzktOS42MzZhMTkuNDggMTkuNDggMCAwIDEgLTIuNDk3LTkuNTU2Yy4wMDQtMTAuNzQyIDguNzQ1LTE5LjQ4IDE5LjQ4Ni0xOS40OGExOS4zNjcgMTkuMzY3IDAgMCAxIDEzLjc4NCA1LjcxMyAxOS4zNjIgMTkuMzYyIDAgMCAxIDUuNzAyIDEzLjc4MWMtLjAwNCAxMC43NDEtOC43NDYgMTkuNDgtMTkuNDg2IDE5LjQ4YTE5LjUzNSAxOS41MzUgMCAwIDEgLTkuMTQ0LTIuMjc3bC05Ljg3NSAyLjU4OWEuNDU3LjQ1NyAwIDAgMSAtLjEyNy4wMTd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI0LjAxNCA1YTE4Ljg2NyAxOC44NjcgMCAwIDEgMTMuNDMgNS41NjYgMTguODY2IDE4Ljg2NiAwIDAgMSA1LjU1NiAxMy40MjhjLS4wMDQgMTAuNDY1LTguNTIyIDE4Ljk4LTE4Ljk4NiAxOC45OGgtLjAwOGExOC45NjUgMTguOTY1IDAgMCAxIC05LjA3My0yLjMxMWwtMTAuMDY1IDIuNjQgMi42OTQtOS44MzVhMTguOTQxIDE4Ljk0MSAwIDAgMSAtMi41MzUtOS40ODljLjAwNS0xMC40NjUgOC41MjEtMTguOTc5IDE4Ljk4Ny0xOC45NzltMC0xYy0xMS4wMTYgMC0xOS45ODIgOC45NjItMTkuOTg3IDE5Ljk3OWEyMC4wMSAyMC4wMSAwIDAgMCAyLjQ2MSA5LjYyMmwtMi41ODUgOS40MzlhLjk5OC45OTggMCAwIDAgMS4yMTkgMS4yMzFsOS42ODctMi41NGEyMC4wMjYgMjAuMDI2IDAgMCAwIDkuMTk3IDIuMjQ0YzExLjAyNCAwIDE5Ljk5LTguOTYzIDE5Ljk5NS0xOS45OGExOS44NTYgMTkuODU2IDAgMCAwIC01Ljg0OC0xNC4xMzUgMTkuODY5IDE5Ljg2OSAwIDAgMCAtMTQuMTM5LTUuODZ6IiBmaWxsPSIjY2ZkOGRjIi8+PHBhdGggZD0ibTM1LjE3NiAxMi44MzJhMTUuNjczIDE1LjY3MyAwIDAgMCAtMTEuMTU3LTQuNjI2Yy04LjcwNCAwLTE1Ljc4MyA3LjA3Ni0xNS43ODcgMTUuNzc0YTE1LjczOCAxNS43MzggMCAwIDAgMi40MTMgOC4zOTZsLjM3Ni41OTctMS41OTUgNS44MjEgNS45NzMtMS41NjYuNTc3LjM0MmExNS43NSAxNS43NSAwIDAgMCA4LjAzMiAyLjE5OWguMDA2YzguNjk4IDAgMTUuNzc3LTcuMDc3IDE1Ljc4LTE1Ljc3NmExNS42OCAxNS42OCAwIDAgMCAtNC42MTgtMTEuMTYxeiIgZmlsbD0iIzQwYzM1MSIvPjxwYXRoIGQ9Im0xOS4yNjggMTYuMDQ1Yy0uMzU1LS43OS0uNzI5LS44MDYtMS4wNjgtLjgyLS4yNzctLjAxMi0uNTkzLS4wMTEtLjkwOS0uMDExcy0uODMuMTE5LTEuMjY1LjU5NC0xLjY2MSAxLjYyMi0xLjY2MSAzLjk1NiAxLjcgNC41OSAxLjkzNyA0LjkwNiAzLjI4MiA1LjI1OSA4LjEwNCA3LjE2MWM0LjAwNyAxLjU4IDQuODIzIDEuMjY2IDUuNjkzIDEuMTg3czIuODA3LTEuMTQ3IDMuMjAyLTIuMjU1LjM5NS0yLjA1Ny4yNzctMi4yNTVjLS4xMTktLjE5OC0uNDM1LS4zMTYtLjkwOS0uNTU0cy0yLjgwNy0xLjM4NS0zLjI0Mi0xLjU0My0uNzUxLS4yMzctMS4wNjguMjM4Yy0uMzE2LjQ3NC0xLjIyNSAxLjU0My0xLjUwMiAxLjg1OS0uMjc3LjMxNy0uNTU0LjM1Ny0xLjAyOC4xMTlzLTIuMDAyLS43MzgtMy44MTUtMi4zNTRjLTEuNDEtMS4yNTctMi4zNjItMi44MS0yLjYzOS0zLjI4NS0uMjc3LS40NzQtLjAzLS43MzEuMjA4LS45NjguMjEzLS4yMTMuNDc0LS41NTQuNzEyLS44MzEuMjM3LS4yNzcuMzE2LS40NzUuNDc0LS43OTEuMTU4LS4zMTcuMDc5LS41OTQtLjA0LS44MzEtLjExNy0uMjM4LTEuMDM5LTIuNTg0LTEuNDYxLTMuNTIyeiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+'); }
.linkedin { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PHBhdGggZD0iTTQyIDM3YTUgNSAwIDAgMS01IDVIMTFhNSA1IDAgMCAxLTUtNVYxMWE1IDUgMCAwIDEgNS01aDI2YTUgNSAwIDAgMSA1IDV2MjZ6IiBmaWxsPSIjMDI4OEQxIi8+PHBhdGggZD0iTTEyIDE5aDV2MTdoLTV6bTIuNDg1LTJoLS4wMjhDMTIuOTY1IDE3IDEyIDE1Ljg4OCAxMiAxNC40OTkgMTIgMTMuMDggMTIuOTk1IDEyIDE0LjUxNCAxMmMxLjUyMSAwIDIuNDU4IDEuMDggMi40ODYgMi40OTlDMTcgMTUuODg3IDE2LjAzNSAxNyAxNC40ODUgMTd6TTM2IDM2aC01di05LjA5OWMwLTIuMTk4LTEuMjI1LTMuNjk4LTMuMTkyLTMuNjk4LTEuNTAxIDAtMi4zMTMgMS4wMTItMi43MDcgMS45OS0uMTQ0LjM1LS4xMDEgMS4zMTgtLjEwMSAxLjgwN3Y5aC01VjE5aDV2Mi42MTZDMjUuNzIxIDIwLjUgMjYuODUgMTkgMjkuNzM4IDE5YzMuNTc4IDAgNi4yNjEgMi4yNSA2LjI2MSA3LjI3NEwzNiAzNnoiIGZpbGw9IiNGRkYiLz48L3N2Zz4='); }
.twitter { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCIgY2xpcC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNMzggNDJIMTBhNCA0IDAgMCAxLTQtNFYxMGE0IDQgMCAwIDEgNC00aDI4YTQgNCAwIDAgMSA0IDR2MjhhNCA0IDAgMCAxLTQgNHoiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZmlsbD0iIzIxMjEyMSIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Ik0zNC4yNTcgMzRIMjcuODJMMTMuODI5IDE0aDYuNDM3em0tNS42Ny0xLjY5NmgyLjU2M0wxOS40OTkgMTUuNjk2aC0yLjU2M3oiLz48cGF0aCBkPSJNMTUuODY2IDM0bDcuMjAzLTguMzQ0LS45NDItMS4yNDlMMTMuODIzIDM0em04LjU4NC0xMi4yNzlsLjkwNSAxLjI4OUwzMy4xMzYgMTRoLTJ6Ii8+PC9nPjwvc3ZnPg=='); }
</style>
${icons.split(' ').map(icon => `<a href="${this.getShareLink(icon, url, text)}" class="${icon}" target="_blank"></a>`).join('')}
`;
}
}
customElements.define('social-icons', SocialIcons);
</script>
</body>
</html>
Este bloco de código define um novo elemento HTML personalizado, que pode ser usado para adicionar ícones de compartilhamento em seu site. Simplesmente copie e cole este código em seu projeto para começar.
Veja o código acima em funcionamento:
Para entender como nosso componente de ícones de compartilhamento social funciona, vamos detalhar o seu código. A compreensão dessas partes facilitará a personalização e a implementação no seu próprio projeto.
<social-icons>
<social-icons icons="whatsapp facebook twitter linkedin pinterest" text="Veja este site incrível!" url="https://www.exemplo.com"></social-icons>
A tag <social-icons>
pode ser personalizada com vários atributos para adequar-se às suas necessidades específicas de compartilhamento social. Aqui estão os atributos que você pode definir:
Configurando esses atributos, você pode customizar os ícones de compartilhamento para se adequarem ao conteúdo e estilo do seu site, promovendo uma experiência de usuário mais integrada e funcional.
SocialIcons
class SocialIcons extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
}
No construtor da classe SocialIcons
, usamos super()
para chamar o construtor da classe pai, HTMLElement
, herdando suas propriedades e métodos. A linha this.attachShadow({ mode: 'open' })
inicia um shadow DOM no modo "open" para o componente. Isso cria um espaço isolado que encapsula o HTML, CSS e JavaScript do componente, evitando interferências com o resto do documento e permitindo estilos e scripts específicos do componente.
connectedCallback()
connectedCallback() {
this.render();
}
O método connectedCallback()
é um dos ciclos de vida de um Web Component, chamado automaticamente pelo navegador quando o componente é inserido no DOM. Aqui, ele invoca o método render()
, responsável por construir ou atualizar o conteúdo interno do componente. Essa abordagem garante que o componente seja corretamente renderizado assim que estiver pronto para ser exibido na página, permitindo que qualquer lógica de inicialização necessária seja executada.
Esse mecanismo é fundamental para a dinâmica dos componentes web personalizados, assegurando que o componente saiba quando começar a se autoconfigurar e apresentar seu conteúdo, como os ícones de compartilhamento social, baseado nos atributos definidos pelo usuário.
attributeChangedCallback()
attributeChangedCallback(name, oldValue, newValue) {
this.render();
}
Quando um atributo do componente (como icons
, text
ou url
) é alterado, o método attributeChangedCallback()
é chamado. Este método reage às mudanças invocando this.render()
para atualizar o componente com os novos valores dos atributos, garantindo que a exibição esteja sempre sincronizada com os dados mais recentes.
getShareLink()
getShareLink(network, url, text) {
switch (network) {
case 'facebook':
return `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`;
case 'whatsapp':
return `https://api.whatsapp.com/send?text=${encodeURIComponent(text + ' ' + url)}`;
case 'twitter':
return `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}`;
case 'linkedin':
return `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`;
case 'pinterest':
return `https://pinterest.com/pin/create/button/?url=${encodeURIComponent(url)}`;
default:
return '';
}
}
A função getShareLink()
constrói e retorna a URL de compartilhamento para a rede social especificada pelo argumento network
. Utiliza o url
da página que será compartilhada e o text
opcional para compor a mensagem. Cada rede social tem seu próprio formato de URL de compartilhamento, tratado dentro do switch
, permitindo assim que o componente <social-icons>
seja versátil e compatível com múltiplas plataformas.
render()
render() {
const iconsAttr = this.getAttribute('icons');
const icons = (!iconsAttr || iconsAttr === 'auto') ? 'whatsapp facebook twitter linkedin pinterest' : iconsAttr.split(' ');
const text = this.getAttribute('text') || '';
const url = this.getAttribute('url') || document.location.href;
this.shadowRoot.innerHTML = `
<style>
:host {
display: inline-flex;
flex-direction: row;
gap: 4px;
}
a {
width: 48px;
height: 48px;
background-size: cover;
display: inline-block;
transition: scale 0.3s ease;
}
a:hover {
scale: 1.2;
}
/* Estilos específicos de ícones aqui */
//
// Lista de redes sociais com o logotipo em SVG
//
</style>
${icons.map(icon => `<a href="${this.getShareLink(icon, url, text)}" class="${icon}" target="_blank"></a>`).join('')}
`;
}
O método render()
é chamado para atualizar o conteúdo do shadow DOM do componente. Ele verifica os atributos icons
, text
, e url
, e utiliza esses valores para construir o HTML dos ícones de compartilhamento. Os ícones são definidos pelos nomes das redes sociais especificados em icons
, e para cada um, é gerado um link utilizando a função getShareLink()
. Esse método garante que o componente reflita os valores mais atuais dos seus atributos, permitindo uma personalização flexível e uma integração fácil em qualquer página web.
O componente <social-icons>
é uma ferramenta eficaz para adicionar funcionalidades de compartilhamento social ao seu site, permitindo personalização para se adequar a diferentes estilos e necessidades.