获取范围的开始和结束偏移量相对于其父容器的值

获取范围的开始和结束偏移量相对于其父容器的值

假设我有这个HTML元素:

<div id="parent">
 Hello everyone! <a>This is my home page</a>
 <p>Bye!</p></div>

用户用鼠标选择“家”。

我想知道有多少个字符#parent他的选择开始(从结尾有多少个字符)#parent他的选择结束)。即使他选择了一个HTML标记,这也是可行的。(我需要它在所有浏览器中工作)

range.startOffset看起来很有希望,但它是一个相对于范围的直接容器的偏移量,并且只有当容器是文本节点时才是字符偏移。


ibeautiful
浏览 537回答 3
3回答

慕姐4208626

我知道这已经有一年的历史了,但这篇文章是很多关于找到卡雷特职位的问题的最佳搜索结果,我觉得这很有用。在内容可编辑div中将元素从一个位置拖放到另一个位置后,我试图使用Tim上面的优秀脚本找到新的光标位置。它在FF和IE中运行良好,但在Chrome中,拖动操作突出显示了拖动开始和结束之间的所有内容,从而导致返回caretOffset太大或太小(按选定区域的长度)。我在第一个if语句中添加了几行代码,以检查是否选择了文本并相应地调整结果。新的声明如下。请原谅我在这里添加这个信息是不合适的,因为这不是OP想要做的事情,但是正如我所说的,几个关于卡雷特职位信息的搜索让我找到了这篇文章,所以它(希望)有可能帮助到其他人。Tim的第一个if语句,增加了行(*):if&nbsp;(typeof&nbsp;window.getSelection&nbsp;!=&nbsp;"undefined")&nbsp;{ &nbsp;&nbsp;var&nbsp;range&nbsp;=&nbsp;window.getSelection().getRangeAt(0); &nbsp;&nbsp;var&nbsp;selected&nbsp;=&nbsp;range.toString().length;&nbsp;//&nbsp;* &nbsp;&nbsp;var&nbsp;preCaretRange&nbsp;=&nbsp;range.cloneRange(); &nbsp;&nbsp;preCaretRange.selectNodeContents(element); &nbsp;&nbsp;preCaretRange.setEnd(range.endContainer,&nbsp;range.endOffset); &nbsp;&nbsp;if(selected){&nbsp;//&nbsp;* &nbsp;&nbsp;&nbsp;&nbsp;caretOffset&nbsp;=&nbsp;preCaretRange.toString().length&nbsp;-&nbsp;selected;&nbsp;//&nbsp;* &nbsp;&nbsp;}&nbsp;else&nbsp;{&nbsp;//&nbsp;* &nbsp;&nbsp;&nbsp;&nbsp;caretOffset&nbsp;=&nbsp;preCaretRange.toString().length;&nbsp; &nbsp;&nbsp;}&nbsp;//&nbsp;*}

繁华开满天机

经过几天的实验,我发现了一种看起来很有前途的方法。因为selectNodeContents()不处理<br>标记正确,我编写了一个自定义算法来确定每个标记的文本长度。node在一个contenteditable..为了计算例如选择开始,我总结了前面所有节点的文本长度。那样的话,我可以句柄(多)换行:var&nbsp;editor&nbsp;=&nbsp;null;var&nbsp;output&nbsp;=&nbsp;null;const&nbsp;getTextSelection&nbsp;=&nbsp;function&nbsp;(editor)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;selection&nbsp;=&nbsp;window.getSelection(); &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(selection&nbsp;!=&nbsp;null&nbsp;&&&nbsp;selection.rangeCount&nbsp;>&nbsp;0)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;range&nbsp;=&nbsp;selection.getRangeAt(0); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start:&nbsp;getTextLength(editor,&nbsp;range.startContainer,&nbsp;range.startOffset), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end:&nbsp;getTextLength(editor,&nbsp;range.endContainer,&nbsp;range.endOffset) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;}const&nbsp;getTextLength&nbsp;=&nbsp;function&nbsp;(parent,&nbsp;node,&nbsp;offset)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;textLength&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(node.nodeName&nbsp;==&nbsp;'#text') &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textLength&nbsp;+=&nbsp;offset; &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;offset;&nbsp;i++) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textLength&nbsp;+=&nbsp;getNodeTextLength(node.childNodes[i]); &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(node&nbsp;!=&nbsp;parent) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textLength&nbsp;+=&nbsp;getTextLength(parent,&nbsp;node.parentNode,&nbsp;getNodeOffset(node)); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;textLength;}const&nbsp;getNodeTextLength&nbsp;=&nbsp;function&nbsp;(node)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;textLength&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(node.nodeName&nbsp;==&nbsp;'BR') &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textLength&nbsp;=&nbsp;1; &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if&nbsp;(node.nodeName&nbsp;==&nbsp;'#text') &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textLength&nbsp;=&nbsp;node.nodeValue.length; &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if&nbsp;(node.childNodes&nbsp;!=&nbsp;null) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;node.childNodes.length;&nbsp;i++) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textLength&nbsp;+=&nbsp;getNodeTextLength(node.childNodes[i]); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;textLength;}const&nbsp;getNodeOffset&nbsp;=&nbsp;function&nbsp;(node)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;node&nbsp;==&nbsp;null&nbsp;?&nbsp;-1&nbsp;:&nbsp;1&nbsp;+&nbsp;getNodeOffset(node.previousSibling);}window.onload&nbsp;=&nbsp;function&nbsp;()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;editor&nbsp;=&nbsp;document.querySelector('.editor'); &nbsp;&nbsp;&nbsp;&nbsp;output&nbsp;=&nbsp;document.querySelector('#output'); &nbsp;&nbsp;&nbsp;&nbsp;document.addEventListener('selectionchange',&nbsp;handleSelectionChange);}const&nbsp;handleSelectionChange&nbsp;=&nbsp;function&nbsp;()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(isEditor(document.activeElement))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;textSelection&nbsp;=&nbsp;getTextSelection(document.activeElement); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(textSelection&nbsp;!=&nbsp;null)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;text&nbsp;=&nbsp;document.activeElement.innerText; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;selection&nbsp;=&nbsp;text.slice(textSelection.start,&nbsp;textSelection.end); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(`Selection:&nbsp;[${selection}]&nbsp;(Start:&nbsp;${textSelection.start},&nbsp;End:&nbsp;${textSelection.end})`); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print('Selection&nbsp;is&nbsp;null!'); &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print('Select&nbsp;some&nbsp;text&nbsp;above');}const&nbsp;isEditor&nbsp;=&nbsp;function&nbsp;(element)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;element&nbsp;!=&nbsp;null&nbsp;&&&nbsp;element.classList.contains('editor');}const&nbsp;print&nbsp;=&nbsp;function&nbsp;(message)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(output&nbsp;!=&nbsp;null) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output.innerText&nbsp;=&nbsp;message; &nbsp;&nbsp;&nbsp;&nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log('output&nbsp;is&nbsp;null!');}*&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;font-family:&nbsp;'Georgia',&nbsp;sans-serif; &nbsp;&nbsp;&nbsp;&nbsp;padding:&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;margin:&nbsp;0;}body&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;margin:&nbsp;16px;}.p&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;font-size:&nbsp;16px; &nbsp;&nbsp;&nbsp;&nbsp;line-height:&nbsp;24px; &nbsp;&nbsp;&nbsp;&nbsp;padding:&nbsp;0&nbsp;2px;}.editor&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;border:&nbsp;1px&nbsp;solid&nbsp;#0000001e; &nbsp;&nbsp;&nbsp;&nbsp;border-radius:&nbsp;2px; &nbsp;&nbsp;&nbsp;&nbsp;white-space:&nbsp;pre-wrap;}#output&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;margin-top:&nbsp;16px;}<!DOCTYPE&nbsp;html><html&nbsp;lang="en"><head> &nbsp;&nbsp;&nbsp;&nbsp;<meta&nbsp;charset="UTF-8"> &nbsp;&nbsp;&nbsp;&nbsp;<meta&nbsp;name="viewport"&nbsp;content="width=device-width,&nbsp;initial-scale=1.0"> &nbsp;&nbsp;&nbsp;&nbsp;<script&nbsp;src="./script.js"&nbsp;async></script> &nbsp;&nbsp;&nbsp;&nbsp;<link&nbsp;href="./stylesheet.css"&nbsp;rel="stylesheet"> &nbsp;&nbsp;&nbsp;&nbsp;<title>Caret&nbsp;Position</title></head><body> &nbsp;&nbsp;&nbsp;&nbsp;<p&nbsp;class="editor"&nbsp;contenteditable="true"><em>Write<br></em><br>some&nbsp;<br>awesome&nbsp;<b><em>text&nbsp;</em></b>here...</p> &nbsp;&nbsp;&nbsp;&nbsp;<p&nbsp;id="output">Select&nbsp;some&nbsp;text&nbsp;above</p></body></html>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript