Search code examples
javascripthtmlgoogle-chrome-extensionpopup

How to display pop up message on top of selected text in any website?


I am working on a chrome extension where I need to display a pop-up on the selection of text on any website just like the image attached below.(Similar example is implemented here).

Though I am able to read the content and position, I am not displaying pop-up at the right position. Any help would be appreciated.

Here is the snippet :

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Custom menu on text selection</title>
        <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous" />
        <style>
            .menu {
                display: none;
                position: absolute;
                background: #a4a4a4;
                border-radius: 6px;
            }
        </style>

        <script>
            var pageX, pageY;
            document.addEventListener("mouseup", () => {
                if (document.querySelector(".menu") != null) {
                    document.querySelector(".menu").remove();
                }
                let selection = document.getSelection();
                let selectedText = selection.toString();
                //this div will diplay in popup
                var iDiv = document.createElement("div");
                iDiv.className = "menu";
                iDiv.innerHTML = '<i class="fa fa-copy fa-2x" id="copy-btn"></i>';
                document.body.appendChild(iDiv);
                var menu = document.querySelector(".menu");

                //if the text is not empty show dialog
                if (selectedText !== "") {
                    var range = window.getSelection().getRangeAt(0);
                    let rect = range.getBoundingClientRect();
                    menu.style.display = "block";
                    var left = Math.round(rect.left) + "px";
                    var top = Math.round(rect.top) + "px";
                } else {
                    //if the text is empty hide existing dialog
                    menu.style.display = "none";
                }
            });
            document.addEventListener("mousedown", (e) => {
                pageX = e.pageX;
                pageY = e.pageY;
            });
        </script>
    </head>
    <body>
        <div>
            <p>
                In today’s digital world, when there are thousands of online platforms (maybe more than that!) available over the web, it becomes quite difficult for students to opt for a quality, relevant and reliable platform for
                themselves. Meanwhile, as Computer Science is a very vast field hence students are required to find an appropriate platform that can fulfill all their needs such as – Tutorials & Courses, Placement Preparation, Interview
                Experiences, and various others. And with the same concern, GeeksforGeeks comes in the picture – a one-stop destination for all Computer Science students!!
            </p>
        </div>
    </body>
</html>

This is the expected output:

Expected Output


Solution

  • You can use event clientX and clientY to get the position os selected text and show dynamic pop up there. Example code is attached below. For more refer to andreaswik blog post.

    In html:

    <div>
           <p>
            In today’s digital world, when there are thousands of online platforms
            (maybe more than that!) available over the web, it becomes quite
            difficult for students to opt for a quality, relevant and reliable
            platform for themselves. Meanwhile, as Computer Science is a very vast
            field hence students are required to find an appropriate platform that
            can fulfill all their needs such as – Tutorials & Courses, Placement
            Preparation, Interview Experiences, and various others. And with the
            same concern, GeeksforGeeks comes in the picture – a one-stop
            destination for all Computer Science students!!
          </p>
      
        </div>
    <div>
    

    In CSS file

    
    .speech-bubble {
      position: relative;
      background: #4294da;
      border-radius: .4em;
      color: white;
    }
    
    .speech-bubble:after {
      content: '';
      position: absolute;
      top: 0;
      left: 50%;
      width: 0;
      height: 0;
      border: 12px solid transparent;
      border-bottom-color: #4294da;
      border-top: 0;
      margin-left: -12px;
      margin-top: -12px;
    }
    
    .share-inside {
      background: url('https://awik.io/demo/js-selected-text/twicon.png');
      background-repeat: no-repeat;
      background-position: 10px center;
      background-size: 24px 19px;
    }
    
    .share-inside a {
      display: inline-block;
      text-decoration: none;
      color: #ffffff;
      font-size: 14px;
      padding: 10px;
      padding-left: 40px;
    }
    

    In js

    
    document.addEventListener('mouseup', handlerFunction, false);
    
    // Mouse up event handler function
    function handlerFunction(event) {
        
        if(document.contains(document.getElementById("share-snippet"))) {
            document.getElementById("share-snippet").remove();
        }
        
        // Check if any text was selected
        if(window.getSelection().toString().length > 0) {
    
            // Get selected text and encode it
            const selection = encodeURIComponent(window.getSelection().toString()).replace(/[!'()*]/g, escape);
            
            // Find out how much (if any) user has scrolled
            var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
            
            // Get cursor position
            const posX = event.clientX - 110;
            const posY = event.clientY + 20 + scrollTop;
          
            // Create Twitter share URL
            const shareUrl = 'http://twitter.com/share?text='+selection+'&url=https://awik.io';
            
            // Append HTML to the body, create the "Tweet Selection" dialog
            document.body.insertAdjacentHTML('beforeend', '<div id="share-snippet" style="position: absolute; top: '+posY+'px; left: '+posX+'px;"><div class="speech-bubble"><div class="share-inside"><a href="javascript:void(0);" onClick=\'window.open(\"'+shareUrl+'\", \"\", \"menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600\");\'>TWEET SELECTION</a></div></div></div>');
        }
    }