7

要素の一部を変更できる独自のテキストエディタがありますtextarea。スパン要素で動作するように調整したいと思います。スパンへの特別な愛着はありません。目標は、テキストエリアではなく、誰かにhtmlを編集させることです。IEでは問題なく動作していますが、Mozillaでいくつかの問題が発生しています。

フォーム入力の代わりにスパンを使用しているのでinnerHTML、値の代わりに使用しています。ただし、とは対照的に、selectionStartselectionEnd関数を機能させることができないようです。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);
}

selecionStartonに問題はありinnerHTMLますか?回避策?構文エラー?提案をありがとう。

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が含まれています。この値は、およびそれぞれのプロパティの位置を参照する整数です。RangestartOffsetendOffsettextContentstartContainerendContainer

<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 に答える