从span的innerHTML获取`selectionStart`

use*_*273 6 javascript innerhtml

我有一个自己的文本编辑器,可以让你改变一个textarea元素的部分.我想调整它以使用span元素.我对跨度没有特别的依恋.目标只是让某人编辑html而不是textarea.我在IE中工作正常但是遇到了Mozilla的一些问题.

因为我使用的是span而不是表单输入,所以我使用的是innerHTML代替值.但是,我似乎无法获得selectionStartselectionEnd函数innerHTML相反的工作value.

这是textarea代码工作正常....

HTML

<textarea id="textarea>Some text goes here</textarea><a href="javascript:void() onclick="editText">edit</a>
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

但是,以下适应不限制选择的开始和结束.

HTML

<span id="textarea>Some text goes here</span><a href="javascript:void() onclick="editText">edit</a>
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

有一个问题selecionStartinnerHTML?解决方法?语法错误?谢谢你的任何建议.

Max*_*Art 4

首先,不要用于innerHTML此类事情。textContent是去这里的路。

我假设这里使用的是符合标准的浏览器或 IE9+。

要做的第一件事是获取文档选择。你可以通过以下方式做到这一点

var sel = getSelection();
Run Code Online (Sandbox Code Playgroud)

现在,选择可以为空,也可以位于元素之外,因此请检查:

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 {
    ...
Run Code Online (Sandbox Code Playgroud)

此时,rng包含一个Range对象,具有属性startOffsetendOffset。这些值是整数,分别表示和textContent属性的位置。startContainerendContainer

您有一个相当简单的情况,它是一个<span>具有单个文本节点的元素。在这种情况下,rng.startContainerandrng.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);
}
Run Code Online (Sandbox Code Playgroud)

如果 的结构更加复杂displaytext,包含子元素等等,事情就会变得有点棘手。您必须在 的后代树中找到起始节点的文本偏移量displaytext,最好的方法是使用TreeWalker遍历文本节点的对象:

var tw = document.createTreeWalker(displaytext, NodeFilter.SHOW_TEXT, null, null);
Run Code Online (Sandbox Code Playgroud)