7

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

因为我使用的是跨度而不是表单输入,所以我使用innerHTML的是值而不是值。但是,selectionStart与. selectionEnd_innerHTMLvalue

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

有问题selecionStartinnerHTML?解决方法?语法错误?感谢您的任何建议。

4

1 回答 1

4

首先,不要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。该值是整数,分别表示和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);
}

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

var tw = document.createTreeWalker(displaytext, NodeFilter.SHOW_TEXT, null, null);
于 2012-12-14T15:27:47.923 回答