0

つまり、次の HTML コードを例にとると、空白は無視されます。

<p>
  paragraph-text
  <span>
   span text
   <i>it</i>
  </span>
</p>

pNode.innerHTML 内に pNode オブジェクトと "span text" の "a" のインデックスがあり、全体として pNode.innerHTML="paragraph-text<span>span text<i>it</i" であるため、ここでは 23 です。 ></span>」の場合、open span タグもカウントする必要があります。

「spanElement and 2」の期待される要素とオフセットを取得できるように、transform(pElement, 23) のように使用できる既存のライブラリはありますか?

事前に感謝します。よろしく、

スティーブ

4

2 に答える 2

1

innerHTMLを取得し、探しているオフセットの文字を変更し、結果のテキスト ノードを再解析および比較して、変更dataが終了した場所を見つけることで、おそらくそれを行うことができます。

例えば。

function findTextFromMarkupIndex(el1, ix) {
    // make comparison element
    var el2= document.createElement(el1.tagName);
    // replace any other use of * in its HTML out of the way
    var html= el1.innerHTML.split('*').join('x');
    // insert a * at the given index in HTML
    el2.innerHTML= html.substring(0, ix)+'*'+html.substring(ix);
    // search the resulting DOM for the * and return the matching descandent from the original
    return findTextInComparison(el1, el2, '*');
}

function findTextInComparison(el1, el2, text) {
    for (var i= 0; i<el1.childNodes.length; i++) {
        var child1= el1.childNodes[i];
        var child2= el2.childNodes[i];
        if (child2.nodeType===3) { // TEXT_NODE
            var ix= child2.data.indexOf(text);
            if (ix!==-1)
                return [child1, ix];
        } else if (child2.nodeType===1) { // ELEMENT_NODE
            var result= findTextInComparison(child1, child2, text);
            if (result!==null)
                return result;
        }
    }
    return null;
}

テストされていませんが、テキスト コンテンツ内の文字については動作するはずです。必要に応じて属性値の内部も参照するように拡張できますが、要素やエンティティ/文字参照などのマークアップ内でインデックス ポイントを実行することはできませんでした。これを機能させるには、基本的に HTML パーサー全体を作成する必要があります。

これは珍しい要件のように聞こえますが、正確には何をしようとしているのでしょうか? innerHTMLこのプロパティのマークアップ出力の正確な形式はまったく標準化されていないため、内のインデックスは非常に壊れやすい可能性があります。

于 2010-01-21T16:31:25.127 に答える
1

あなたが話していることは、 Internet Explorer を除くすべての主要なブラウザーに実装されているDOM Rangeのようなものです。innerHTML の実装は大きく異なるため、HTML 内の文字オフセットの観点から位置を指定することはお勧めできません。DOM 範囲には開始境界と終了境界があり、それぞれがノードとそのノード内のオフセットに関して指定されます。あなたの例の場合、場所を表す Range を作成できます。

var span = pNode.childNodes[1];
var spanText = span.firstChild;
var range = document.createRange();

// Next line takes into account whitespace at the start of the text node
range.setStart(spanText, 6); 

// For illustration, create a range that contains the letter "a" and selects it
range.setEnd(spanText, 7);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);

Range を取得したら、ノードの挿入、ユーザー選択の定義、Range によってカプセル化されたコンテンツへのフォーマットの適用など、さまざまなことに使用できます。

IE は、 TextRangeと呼ばれるまったく異なるオブジェクトを定義します。これは、根本的に異なるテキストベースのアプローチを持ちますが、ほとんど同じ目的を果たします。前の例と同等の TextRange を取得するには、次を使用できます。

var textRange = document.body.createTextRange();
textRange.moveToElementText(pNode);
textRange.moveStart("character", 17);
textRange.collapse();

// For illustration, create a range that contains the letter "a" and selects it
textRange.moveEnd("character", 1);
textRange.select();
于 2010-01-21T16:34:03.597 に答える