Javascript 获取选定的文本位置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5176761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting selected text position
提问by Ecarrion
Currently I'm getting the selected text in the browser doing this:
目前我正在浏览器中获取选定的文本:
window.getSelection();
Now I need to show a tooltip above that text when pressing a custom key(note that the mouse could not be over the text anymore), so in order to do that I need the absolute position of that selected text.
现在我需要在按下自定义键时在该文本上方显示一个工具提示(请注意,鼠标不能再位于文本上),因此为了做到这一点,我需要该选定文本的绝对位置。
Is there a way to do that, maybe wrapping that text inside a tag and then getting the offsets? It just has to work in Chrome, not all browsers.
有没有办法做到这一点,也许将该文本包装在标签中然后获取偏移量?它只需要在 Chrome 中运行,而不是在所有浏览器中运行。
采纳答案by Tim Down
The easiest way is to insert a temporary marker element at the start or end of the selection and get its position. I've demonstrated how to do this before on Stack Overflow: How can I position an element next to user text selection?
最简单的方法是在选择的开始或结束处插入一个临时标记元素并获取其位置。我之前已经在 Stack Overflow 上演示了如何执行此操作:如何将元素放置在用户文本选择旁边?
回答by Jerinaw
s = window.getSelection();
Returns a Selection. So try
返回一个选择。所以试试
s = window.getSelection();
oRange = s.getRangeAt(0); //get the text range
oRect = oRange.getBoundingClientRect();
oRect will be the bounding rectangle in client (fixed) coordinates.
oRect 将是客户端(固定)坐标中的边界矩形。
回答by lowatt
Before using getBoundingClientRect
, you need to know this note:
在使用之前getBoundingClientRect
,你需要知道这个注意事项:
CSSOM working draft specifies that it returns a ClientRect for each border box
CSSOM 工作草案指定它为每个边框框返回一个 ClientRect
And by this 'standard':
按照这个“标准”:
For an inline element, the two definitions are the same. But for a block element, Mozilla will return only a single rectangle.
对于内联元素,这两个定义是相同的。但是对于块元素,Mozilla 只会返回一个矩形。
So if anyone reading this post wants a general solution for more precise positions and layouts of selected texts, I suggest the following approaches:
因此,如果任何阅读这篇文章的人想要一个更精确的选定文本位置和布局的通用解决方案,我建议采用以下方法:
Option 1:Find exact starting and and ending point of texts by inserting invisible elements. Then calculate selected line rectangles with extracted computed line height and container width. APIs in use: window.getComputedStyle.
选项 1:通过插入不可见元素来查找文本的确切起点和终点。然后使用提取的计算线高和容器宽度计算选定的线矩形。使用中的 API:window.getComputedStyle。
- Pro: the result would be most precise for each line of text.
- Con: 1) If the selection is across several nodes with different line heights and widths, the algorithm becomes complex. 2) And you need to implement the computation algorithm, which is too time consuming when implementing a simple feature.
- 优点:每行文本的结果将是最精确的。
- 缺点:1)如果选择跨多个具有不同线高和宽度的节点,则算法变得复杂。2) 并且需要实现计算算法,实现简单的特征太耗时。
Option 2:Wrap each text with a carefully styled inline element, extracting layout of each box, and merge results into lines.
选项 2:用精心设计的内联元素包裹每个文本,提取每个框的布局,并将结果合并成行。
- Pro: Works for all continuous selections (that basically means all cases in current mainstream browser implementations.). Good enough precision for each line of texts.
- Con: 1) Its result is a little inaccurate in some cases, as it adds error widths of kerning. 2) It's slow on very large selection of texts.
- Pro:适用于所有连续选择(这基本上意味着当前主流浏览器实现中的所有情况。)。每行文本的精度足够好。
- 缺点:1) 在某些情况下,它的结果有点不准确,因为它增加了字距调整的错误宽度。2)选择非常大的文本时速度很慢。
For option 2, rangeblockis an existing implementation with an easy API which gives you the absolution layout of each line of text:
对于选项 2,rangeblock是一个现有的实现,带有一个简单的 API,它为您提供了每行文本的绝对布局:
let block = rangeblock.extractSelectedBlock(window, document);
console.info("Text layout: " + JSON.stringify(block.dimensions));
// output: Text layout: {Left: 100, Top: 90, Width: 200, Height: 50}