从 span 的 innerHTML 获取`selectionStart`
Posted
技术标签:
【中文标题】从 span 的 innerHTML 获取`selectionStart`【英文标题】:Getting `selectionStart` from a span's innerHTML 【发布时间】:2012-12-02 14:04:24 【问题描述】:我有一个你自己的文本编辑器,可以让你更改textarea
元素的一部分。我想调整它以使用跨度元素。我对跨度没有特别的依恋。目标只是让某人编辑 html 而不是 textarea。我在 IE 中运行良好,但在 Mozilla 中遇到了一些问题。
由于我使用的是跨度而不是表单输入,因此我使用的是innerHTML
而不是值。但是,我似乎无法让 selectionStart
和 selectionEnd
函数在 innerHTML
上工作,而不是在 value
上工作。
这是运行良好的textarea
代码....
html
<textarea id="textarea>Some text goes here</textarea><a href="javascript:void() onclick="editText">edit</a>
JS
function editText()
var len = displaytext.value.length;
var start = displaytext.selectionStart;
var end = displaytext.selectionEnd;
var sel = displaytext.value.substring(start, end); returns selection ok
alert(sel);
但是,下面的改编并不限制选择开始和结束。
html
<span id="textarea>Some text goes here</span><a href="javascript:void() onclick="editText">edit</a>
JS
function editText()
var len = displaytext.innerHTML.length; //works ok
var start = displaytext.selectionStart; //does not seem to work
var end = displaytext.selectionEnd; //does not seem to work
var sel = displaytext.innerHTML.substring(start, end); //returns whole innerHTML not selection
alert(sel);
innerHTML
上的selecionStart
有问题吗?解决方法?语法错误?感谢您的任何建议。
【问题讨论】:
innerHTML
和 value
会导致什么结果?您可以在警报中获取这些结果并将结果粘贴到此处吗? (或链接)
它返回未定义。认为我发现 selectionStart 仅适用于 textarea 和 text 元素。看起来我需要替代适用于跨度的 selectionStart 和 selectionEnd ...
how to get span selected portion using Javascript 的可能副本看这里(第一个答案解释了它)
【参考方案1】:
首先,不要将innerHTML
用于此类事情。 textContent
是这里的路。
我假设这里是符合标准的浏览器或 IE9+。
首先要做的是获取文档选择。你可以这样做
var sel = getSelection();
现在,选择可以是空的,也可以在元素之外,所以检查一下:
var rng, startSel, endSel, sel;
if (!sel.rangeCount
|| displaytext.compareDocumentPosition((rng = sel.getRangeAt(0)).startContainer) === Node.DOCUMENT_POSITION_PRECEDING
|| displaytext.compareDocumentPosition(rng.endContainer) === Node.DOCUMENT_POSITION_FOLLOWING)
sel = "";
else
...
此时,rng
包含一个Range
对象,具有startOffset
和endOffset
属性。该值是整数,分别表示startContainer
和endContainer
的textContent
属性的位置。
您有一个相当简单的案例,它是一个带有单个文本节点的<span>
元素。在这种情况下,rng.startContainer
和 rng.endContainer
将始终是 displaytext
,或者某个前面或后面的元素,但不是 displaytext
的后代。
...
else
startSel = displaytext.compareDocumentPosition(rng.startContainer) === Node.DOCUMENT_POSITION_FOLLOWING ? 0 : rng.startOffset;
endSel = displaytext.compareDocumentPosition(rng.endContainer) === Node.DOCUMENT_POSITION_PRECEDING ? displaytext.textContent.length : rng.endOffset;
sel = displaytext.textContent.substring(startSel, endSel);
如果displaytext
的结构更复杂,有子元素等等,事情就会变得有点棘手。您必须在 displaytext
的后代树中找到起始节点的文本偏移量,最好的方法是使用 TreeWalker
对象遍历文本节点:
var tw = document.createTreeWalker(displaytext, NodeFilter.SHOW_TEXT, null, null);
【讨论】:
嗨,textContent 工作得很好,但是,我没有让整个脚本工作......jsfiddle.net/u9Re7/2 我错过了什么吗?非常感谢。 @user1904273 是的,抱歉,第一个if
语句中有一个额外的括号。为您修复了the fiddle。
没关系。让它工作。在 Preceding 之后有一个额外的右括号。再次感谢!以上是关于从 span 的 innerHTML 获取`selectionStart`的主要内容,如果未能解决你的问题,请参考以下文章