从span的innerHTML获取`selectionStart`

时间:2012-12-14 14:48:16

标签: 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>

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);
}

selecionStart上的innerHTML是否有问题?解决方法?语法错误?谢谢你的任何建议。

1 个答案:

答案 0 :(得分:3)

首先,不要将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个对象,其属性为startOffsetendOffset。此值是整数,分别指textContentstartContainer的{​​{1}}属性的位置。

你有一个相当简单的案例,它是一个endContainer元素,只有一个文本节点。在这种情况下,<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