How to create tooltip over text selection without wrapping?
Asked Answered
L

2

9

My end goal is to create a tooltip over a text selection. The user will then be able to interact with the tooltip similar to this. Please note that I was able to accomplish this by wrapping selected text in a tag and then creating the tooltip on it however this is no longer an option for me due to some other requirements and functionality issues. If you notice in the image above in element inspector, the selected text is not wrapped in any kind of tag, the tooltip is just created over the selection. I have already looked at this and it will not work for me because mouse position may not be the same as the end of selection. I need the actual selection position.

General question: What is the best way to accomplish this? More specific questions:

  • Should I be using the coordinates of the selection? If so is there a way to get the coordinates of the top corners of the rectangular selection so I can find the mid point and create a the tooltip over that.
  • Is there a way to get that selection as an element? So I can just place a tooltip over that? (Note the selection can be multiple nodes)
Lionize answered 18/8, 2013 at 19:4 Comment(5)
I've been looking for the same thing recently and I've found Highlighter.js.Catfish
Thanks. This is definitely something I can use.Lionize
I actually found something better, it's called Popline. I hope it helps.Catfish
@Catfish have you had the code? The page was not found!Bilicki
github.com/sighmon/highlighter.jsCatfish
R
19

Assuming something selected

var selection = window.getSelection(),      // get the selection then
    range = selection.getRangeAt(0),        // the range at first selection group
    rect = range.getBoundingClientRect(); // and convert this to useful data

rect is now a Object which holds the positions relative the the current scroll coordinates of the Window. More info on this here. If you want to be even more precise, you can use getClientRects which returns a list of such Objects, which you would then have to put together to form the area of the selection.

Now, to draw a box around it (I'll take the easy route using fixed for demonstration purposes)

var div = document.createElement('div');   // make box
div.style.border = '2px solid black';      // with outline
div.style.position = 'fixed';              // fixed positioning = easy mode
div.style.top = rect.top + 'px';       // set coordinates
div.style.left = rect.left + 'px';
div.style.height = rect.height + 'px'; // and size
div.style.width = rect.width + 'px';
document.body.appendChild(div);            // finally append

You will probably want to take into consideration the scroll position so you can use absolute positioning. If there are no other scrollable elements, this means you just need to factor in the values of window.scrollX and window.scrollY, which are the position of the window's x and y coordinates in pixels at the time they're accessed.

var div = null;

function drawBorderAroundSelection() {
  var selection = window.getSelection(), // get the selection then
    range = selection.getRangeAt(0), // the range at first selection group
    rect = range.getBoundingClientRect(); // and convert this to useful data

  if (rect.width > 0) {
    if (div) {
      div.parentNode.removeChild(div);
    }
    div = document.createElement('div'); // make box
    div.class = 'rect';
    div.style.border = '2px solid black'; // with outline
    div.style.position = 'fixed'; // fixed positioning = easy mode
    div.style.top = rect.top + 'px'; // set coordinates
    div.style.left = rect.left + 'px';
    div.style.height = rect.height + 'px'; // and size
    div.style.width = rect.width + 'px';
    document.body.appendChild(div); // finally append
  }
}

window.onmouseup = drawBorderAroundSelection;
<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ut dolor porta neque vulputate auctor et a ligula. Quisque bibendum risus magna, eget feugiat erat faucibus sed. Phasellus sed massa elementum, laoreet ipsum non, dignissim orci. Aenean lobortis
  nunc et purus molestie, vel consectetur ligula dapibus. In ut lorem mattis, commodo nisi aliquam, porta ante. Curabitur sit amet libero sed justo finibus porttitor. Donec ac est ultrices, pretium diam sed, blandit nunc. Morbi consequat finibus augue
  vel ultricies. Vestibulum efficitur ante vitae cursus accumsan. Vestibulum rutrum ex ex, a egestas nisi malesuada eu. Pellentesque fermentum, ante id convallis luctus, tellus lectus viverra diam, sit amet convallis ligula lorem sit amet neque.
</p>
Rauwolfia answered 18/8, 2013 at 19:10 Comment(5)
This is just a sub question. How would you do absolute positioning? I am relatively new to web stuff. I noticed the rectangle stays at its original position (due to fixed positioning) when the window is resized so the text is no longer in the div. Sorry, if you think its a different question, I can create another post.Lionize
@Lionize factor in the values of window.scrollX and window.scrollY; but it gets more and more complicated the more scrollable elements you have nestedRauwolfia
@fracz as you changed the event I was using in the snippet, as it stands the snippet no longer has the same behaviour in Google Chrome, where the event fires as you're creating the selection and then the outlining div blocks it, meaning the selection jumps to the end of the node and not where your cursor wasRauwolfia
First of all, I have not changed any part of your answer - just added the runnable snippet to demostrate the PoC. Hovewer, it seems that the first attitude with mouseup event was better indeed, although the selectionchanged feels more adequate. Rolled back.Yukoyukon
@Yukoyukon ah, sorry - I only saw/compared the latest revision. Thanks for adding the snippet!Rauwolfia
S
4

$(document).ready(function () {
  function tweetButtonClick() {
    let selectedText = document.getSelection().toString();
    /*window.open(
      "https://twitter.com/intent/tweet?url=https://www.linkedin.com/in/harsha-vardhan-ch-245197bb/&text=" +
        selectedText
    );*/
    console.log("This is your selected text: ",selectedText);
  }

  const textSelectionTooltipContainer = document.createElement("div");
  textSelectionTooltipContainer.setAttribute(
    "id",
    "textSelectionTooltipContainer"
  );
  textSelectionTooltipContainer.innerHTML = `<button id="textShareTwitterBtn">TWEET</button>`;
  const bodyElement = document.getElementsByTagName("BODY")[0];

  $("body").on("click", "#textShareTwitterBtn", tweetButtonClick);

  bodyElement.addEventListener("mouseup", function (e) {
    var textu = document.getSelection().toString();
    if (!textu.length) {
      textSelectionTooltipContainer.remove();
    }
  });

  document
    .getElementById("textToSelect")
    .addEventListener("mouseup", function (e) {
      let textu = document.getSelection().toString();
      let matchu = /\r|\n/.exec(textu);
      if (textu.length && !matchu) {
        let range = document.getSelection().getRangeAt(0);
        rect = range.getBoundingClientRect();
        scrollPosition = $(window).scrollTop();
        containerTop = scrollPosition + rect.top - 50 + "px";
        containerLeft = rect.left + rect.width / 2 - 50 + "px";
        textSelectionTooltipContainer.style.transform =
          "translate3d(" + containerLeft + "," + containerTop + "," + "0px)";
        bodyElement.appendChild(textSelectionTooltipContainer);
      }
    });
});
#textSelectionTooltipContainer {
  will-change: transform;
  position: absolute;
  width: 100px;
  height: 40px;
  background: #f7d39d;
  top: 0px;
  left: 0px;
  display: flex;
  padding: 5px 10px;
  box-sizing: border-box;
  justify-content: center;
}

#textSelectionTooltipContainer button {
  font-size: 14px;
  border: 1px solid black;
  background: none;
  cursor: pointer;
  margin: 0 2px;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <link rel='stylesheet' href='shareText.css' />
  <title>Text Share Feature</title>
  <script>

  </script>
</head>

<body>
  
  <div id="textToSelect">
  
    <h1>HTML Ipsum Presents</h1>
  
    <p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em>    Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci,
      sagittis tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>
  
    <h2>Header Level 2</h2>
  
    <ol>
      <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
      <li>Aliquam tincidunt mauris eu risus.</li>
    </ol>
  
    <blockquote>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis
        elit sit amet quam. Vivamus pretium ornare est.</p>
        <p>
        Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis
        </p>
    </blockquote>
  
    <h3>Header Level 3</h3>
  
    <ul>
      <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
      <li>Aliquam tincidunt mauris eu risus.</li>
    </ul>
    <h1>HTML Ipsum Presents</h1>
  
    <p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em>    Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci,
      sagittis tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>
  
    <h2>Header Level 2</h2>
  
    <ol>
      <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
      <li>Aliquam tincidunt mauris eu risus.</li>
    </ol>
  
    <blockquote>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis
        elit sit amet quam. Vivamus pretium ornare est.</p>
        <p>
        Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis
        </p>
    </blockquote>
  
    <h3>Header Level 3</h3>
  
    <ul>
      <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
      <li>Aliquam tincidunt mauris eu risus.</li>
    </ul>
    <h1>HTML Ipsum Presents</h1>
  
    <p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em>    Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci,
      sagittis tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>
  
    <h2>Header Level 2</h2>
  
    <ol>
      <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
      <li>Aliquam tincidunt mauris eu risus.</li>
    </ol>
  
    <blockquote>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis
        elit sit amet quam. Vivamus pretium ornare est.</p>
        <p>
        Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis
        </p>
    </blockquote>
  
    <h3>Header Level 3</h3>
  
    <ul>
      <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
      <li>Aliquam tincidunt mauris eu risus.</li>
    </ul>
    <h1>HTML Ipsum Presents</h1>
  
    <p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em>    Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci,
      sagittis tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>
  
    <h2>Header Level 2</h2>
  
    <ol>
      <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
      <li>Aliquam tincidunt mauris eu risus.</li>
    </ol>
  
    <blockquote>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis
        elit sit amet quam. Vivamus pretium ornare est.</p>
        <p>
        Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis
        </p>
    </blockquote>
  
    <h3>Header Level 3</h3>
  
    <ul>
      <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
      <li>Aliquam tincidunt mauris eu risus.</li>
    </ul>
  </div>
  <script src="shareText.js"></script>
</body>
</html>

window.open lets you open the twitter page(https://twitter.com/intent/tweet) where you can share the selected text and also url.

Sleepless answered 30/12, 2020 at 8:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.