Selection 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。文本选区由用户拖拽鼠标经过文字而产生。要获取用于检查或修改的Selection对象,请调用 window.getSelection()。Range,表示包含节点和部分文本节点的文档片段,可以通过 Selection 对象的 getRangeAt 方法取得,也可以通过 Document 对象的 createRange 方法创建。
在我们日常前端开发中,可能会遇到这样的场景,实现划词翻译、点击取词翻译、编辑器中的复制、粘贴等需求,下面我们通过对这两种需求场景来介绍 Selection 对象 和 Range 对象在实际项目中的应用。
应用一:实现点击取词并翻译
实现基本思路,点击时获取 Selection 对象,并创建选取,通过 Range 的 setStart 和 setEnd 方法扩大文档片段的范围,以空格或者特殊符号为临界状态,终止循环。
1.方法一实现相关逻辑如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 
 | if (window.getSelection) {let selection, range, node, start, end, text, rect, isFun, isText;
 
 
 isFun = !!window.JSInvoker && typeof window.JSInvoker.toggleWordTooltip === 'function';
 
 
 isText = function (text) {
 return text && /^[a-zA-Z]+$/.test(text);
 }
 
 
 isFun && window.JSInvoker.toggleWordTooltip(false);
 
 selection = window.getSelection();
 range = selection.getRangeAt(0);
 node = selection.anchorNode;
 start = range.startOffset;
 end = range.endOffset;
 text = range.toString();
 
 
 while (!/^\s+/.test(text)) {
 if (start === 0) {
 range.setStart(node, start);
 text = range.toString();
 break;
 } else {
 start -= 1;
 range.setStart(node, start);
 text = range.toString();
 }
 if (!isText(text)) {
 start += 1;
 range.setStart(node, start);
 text = range.toString();
 break;
 }
 }
 
 while (!/\s+$/.test(text)) {
 if (end === node.length) {
 range.setEnd(node, end);
 text = range.toString();
 break;
 } else {
 end += 1;
 range.setEnd(node, end);
 text = range.toString();
 }
 if (!isText(text)) {
 end -= 1;
 range.setEnd(node, end);
 text = range.toString();
 break;
 }
 }
 
 
 rect = range.getBoundingClientRect();
 text = text.trim();
 if (isText(text) && isFun && rect) {
 
 window.JSInvoker.toggleWordTooltip(true, text, rect.x, rect.y, rect.width, rect.height);
 } else {
 alert(`Text: ${text}, isFun: ${isFun}, Rect: ${JSON.stringify(rect)}`);
 }
 } else {
 
 }
 
 | 
ps: 文本选中颜色可以通过 CSS3 ::selection 来实现,但是兼容性是个问题,可以通过 rect 属性值来创建个 mask 浮层 position:absolute; 来实现
2.方法二实现方案比较简单,实现代码逻辑如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | if (window.getSelection) {let selection, start, end, word;
 
 selection = window.getSelection();
 
 selection.modify('extend', 'backward', 'word');
 start = selection.toString();
 
 selection.modify('extend', 'forward', 'word');
 end = selection.toString();
 
 selection.modify('move', 'forward', 'character');
 
 word = start + end;
 alert(`Selected Text: ${word}`);
 } else {
 
 }
 
 | 
应用二:实现划词翻译
1.获取划词文本
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | function getSelected () {let selection;
 if (window.getSelection) {
 
 selection = window.getSelection();
 } else if (document.getSelection) {
 
 selection = document.getSelection();
 } else if (document.selection) {
 
 selection = document.selection.createRange().text;
 }
 
 return selection.toString().trim();
 }
 
 | 
2.清空选中文本
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | function removeSelection () {if (window.getSelection) {
 window.getSelection().removeAllRanges();
 } else if (document.getSelection && document.getSelection.empty) {
 document.getSelection().empty();
 } else if (document.selection && document.selection.empty) {
 document.selection.empty();
 }
 }
 
 | 
第三方库
rangy A cross-browser JavaScript range and selection library.
            
            转载申请
            本作品采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,文章内图片请保留全部内容。