如何在没有包装的情况下创建文本选择工具提示?

我的最终目标是在文本选择上创建工具提示。 然后,用户将能够与类似的工具提示进行交互 这个 。 请注意,我能够通过将所选文本包装在标签中然后在其上创建工具提示来实现此目的,但由于某些其他要求和function问题,这不再是我的选项。 如果您在元素检查器中的上图中注意到,所选文本未包含在任何类型的标记中,则仅在选择上创建工具提示。 我已经看过这个并且它对我不起作用,因为鼠标位置可能与选择结束不同。 我需要实际的选择位置。

一般问题:实现这一目标的最佳方法是什么? 更具体的问题:

  • 我应该使用选择的坐标吗? 如果是这样,有办法获得矩形选择的顶角坐标,这样我就可以找到中点并创建一个工具提示。
  • 有没有办法将选择作为一个元素? 所以我可以放一个工具提示吗? (注意选择可以是多个节点)

假设选择了一些东西

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现在是一个Object ,它保存相对于Window当前滚动坐标的位置。 有关这方面的更多信息。 如果您想要更精确,可以使用getClientRects返回此类对象的列表,然后您必须将它们放在一起以形成选择区域。

现在,在它周围画一个盒子(我将采用fixed的简单路线进行演示)

 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 

您可能需要考虑滚动位置,以便使用绝对定位。 如果没有其他可滚动元素,这意味着您只需要考虑window.scrollXwindow.scrollY的值,它们是窗口xy坐标在访问它们时的像素位置。

 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; 
 

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.