DEV Community

Cover image for Create a JavaScript plugin to highlight and tweet text
AlbertoM
AlbertoM

Posted on • Edited on • Originally published at inspiredwebdev.com

Create a JavaScript plugin to highlight and tweet text

This article was originally posted on my blog. Head over to inspiredwebdev.com for more articles and tutorials. Check out my JavaScript course on Educative to learn everything from ES6 to ES2019.

 

Hi, I am Alberto Montalesi, a full-stack self-taught developer. I create JavaScript tutorials and courses on my website inspiredwebdev.com to inspire other developers to grow and build the career that they want.

Create a plugin to highlight and tweet text

Many times I found myself reading a passage on a website and thinking I wanted to share that with my friends or random people of the internet, but few are the times where the website facilitated that process for me.

Usually, I would have to copy the passage I wanted to share, go on Twitter and tweet it but we all know that most people are lazy so, if you want your user to tweet content from your articles/blogs, etc... in this tutorial, I will teach you how to create a simple plugin to do that.

Alternatively, if you don't want to bother with coding it yourself, I've already packaged it for you and you can find it on npm at highlight-to-tweet.

Credits for most of the idea and the code go to this user on WebFlow. I mostly transformed the JQuery code into a native JavaScript code and published it as an npm package.

The plugin we are going to build will work in the following way:

  • A user highlight some text on your page
  • They are prompted to tweet it with a button
  • They click the button and they can tweet it, all without leaving your site

 

Create the tweetHighlighted function

Now that you are ready to start, let's open your JavaScript file and start with:

document.addEventListener('DOMContentLoaded', () => {

    window.tweetHighlighted = () => {
        // our function will be built here
    }

    // we call it once the page loads
    window.tweetHighlighted()
})

The first thing we want to do know is to define some properties that will come in handy later on. Inside of the window.tweetHighlighted = () => { function, we want to add this code:

const settings = {
    node: "<a href='#'>Tweet</a>",
    maxLength: 280,    
    extra: null,
    via: null,
    popupArgs:'width=400,height=400,toolbar=0,location=0',
}

These are the basic settings of our plugin:

  • node defines the element that will be contained in the button that pops up
  • maxLength is the max length allowed for the tweet, here I've set it as 280 because that's the max allowed for a tweet, but if you want to set it lower you can do it
  • extra is simply some extra text that you want to include in your tweets
  • via defines the handler for twitter, if you want to be tagged whenever a user tweets something from your site
  • popupArgs is used to define the twitter popup

Our next step will be to create a button, add it to the DOM and give an event listener to it.

Continuing after the code we just wrote, add this:

let url = '';
let text = '';
const shareButton = document.createElement('div');
shareButton.style.display = 'none';
shareButton.addEventListener('click', (e) => {
    e.preventDefault();
    e.stopPropagation();
    window.open(url, '_blank', settings.popupArgs);
})
const body = document.querySelector('body');
body.appendChild(shareButton);

Firstly, we defined two empty variables that will hold our url and text for the tweet.

Secondly, we created a new div element and assign it to our variable shareButton.

We then hid it with display:'none' and added an event listener to it to listen for click events.

When a user clicks our button we use stopPropagation to avoid the click event to bubble down to the a tag that we assigned above to the node in our settings and we also call window.open passing the url that will be populated later and our arguments to define the size of the window to open.

After that, we are simply adding this newly created element to the body of our page.

One thing you may be wondering is how we are going to identify when the user highlights texts on the page.

The answer to that is simple, we will use the mouseup event and check if the user selected something.

 

Add event listeners to the function

Continuing from where we left, let's add this code:

document.addEventListener('mouseup', (e) => {
    text = getSelectedText();
    const btnExists = shareButton.style.display !== 'none';
    if (btnExists || !text.length){
        return;
    } else {
        appendShareButton(e)
    }
})

 const getSelectedText = () => {
    if (window.getSelection) {
        return window.getSelection().toString();
    } else if (document.selection) {
        return document.selection.createRange().text;
    }
    return '';
};

Awesome, these two functions will ensure that when the user triggers the mouseup event, if there is some text highlighted, we will capture it, store it in our text variable and call the function appendShareButton to add that button to the DOM.

Let's continue and define that function:

const appendShareButton = (e) => {

    url = getTweetURL(text, settings.extra, settings.via);

    shareButton.innerHTML = '';
    shareButton.innerHTML += settings.node;
    shareButton.innerHTML += tweetIcon;
    if(settings.cssClassess && settings.cssClassess.length){
        shareButton.classList.add(settings.cssClassess);
    }
    shareButton.style.top = `${e.pageY}px`;
    shareButton.style.left = `${e.pageX}px`;
    shareButton.style.position = 'absolute';
    shareButton.style.cursor = 'pointer';
    shareButton.style.display = 'flex';
    shareButton.style.justifyContent = 'space-between';
    shareButton.style.alignContent = 'center';
    shareButton.style.alignItems = 'center';
    shareButton.style.opacity = 0;

    shareButton.style.fontFamily = 'Arial, Helvetica, sans-serif';
    shareButton.style.backgroundColor = '#3898EC';
    shareButton.style.padding = '10px 15px';
    shareButton.style.width = '100px'
    shareButton.style.borderRadius = '5px';
    shareButton.style.color = 'white';
    shareButton.firstChild.style.color = 'white';
    shareButton.firstChild.style.textDecoration = 'none';
    shareButton.lastChild.style.fill = 'white';
}

Wow, that is a long function but don't worry, it does not do much. Most of those lines are just styling.

Firstly, we get the create the complete url by calling yet another function that we haven't defined, called getTweetURL, passing it the highlighted text, the extra text and the via handler.

We then define a list of styles on our shareButton to display it and position it appropriately.

The only important ones are the one relative to the positioning of the button, everything else is purely styling.

It may be gross to define each style on a different line like this but I figured it would be clearer for you to see. If you want, you can define styles this way too:

shareButton.style.cssText = `
/* your list of style here, same as how you would add it in a CSS file*/
`

You may have noticed this line: shareButton.innerHTML += tweetIcon;

We haven't defined yet a tweetIcon so let's go outside this function and copy this code:

 const tweetIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/></svg>`;

This is the tweet icon, it's a simple SVG I've found online, this will allow us to don't have to call it from a CDN or somewhere else.

Awesome, now we have a function to append the button to the DOM, we only need to define that function getTweetURL.

Let's do that now:

 

Construct the URL for the tweet

const getTweetURL = function (text, extra, via) {
    let url = 'https://twitter.com/intent/tweet?text=';
    // trim the text to fit in the max allowed 280 characters
    const viaUrl = `&via=${via}`;
    const maxLength = settings.maxLength > 280 ? 280 : settings.maxLength;
    const maxAllowedLength = maxLength - viaUrl.length - extra.length;
    let textToTweet = text;
    if(text.length > maxAllowedLength){
        textToTweet = text.substring(0,maxAllowedLength -1);
    }
    url += encodeURIComponent(textToTweet);
    if (extra)
        url += encodeURIComponent(' ' + extra);

    if (via)
        url += viaUrl

    return url;
    };

Let's break down this function:

  • first, we define the base URL that we need
  • then we create the portion of URL that contains our via handler
  • after that, we calculate how many characters in our text allowed to take, based on the maxLength we defined (or the max of 280), the via handler and the extra text
  • if the text is too long, we use substring to take only a portion of it
  • we then stick everything together and use encodeURIComponent to ensure all characters are escaped properly

There you have it, this function returns a perfect URL to share the tweet.

Now you can try this code on your webpage and you will see that everything should work fine.

If you want a more customizable plugin you can check out the one i've published on Github.

 


Thank you very much for reading. Follow me on DevTo or on my blog at inspiredwebdev or on twitter. Check out Educative.io for interactive programming courses.

Disclaimer: Links to Amazon and Educative are affiliate links, purchases you make will generate extra commissions for me. Thank you


book banner

Get my ebook on Amazon and Leanpub

Top comments (1)

Collapse
 
sigmapie8 profile image
Manav

A word of advice: As many softwares use plugins these days, sometimes it's not obvious what software is the plugin targetting. Please mention the target software as well like Node plugin, or browser plugin, or vs plugin.