2012-03-24 6 views
20

私は、ユーザーが選択したDOM構造のセクション(常に画面上のテキストの選択)を保存/取得している拡張機能を持っています。選択範囲を保存するときに、セクションをSPANタグに囲み、テキストを黄色で強調表示します。これにより、選択されたテキストの周りのDOM構造がさまざまなテキストノードに分割されます。これは、私がこの選択を復元しようとすると(ページを更新せずに)、DOM構造が変更されたときに問題を引き起こすため、問題が発生します。スパンを挿入した後にテキストノードを併合する

私の質問は、SPANを挿入した後にDOM構造が分割されないようにすることです。これを達成できない場合は、元の状態にSPANタグを削除した後、どのようにDOM構造を再構築しますか?

//Insert the span 
var sel = restoreSelection(mootsOnPage[i].startXPath); 
var range = sel.getRangeAt(0).cloneRange(); 
var newNode = document.createElement('span'); 
newNode.className = 'highlightYellow'; 
range.surroundContents(newNode); 


//Original DOM structure 
<p>Hello there, how are you today</p> 


//What the DOM looks like after insertion of SPAN 
<p> 
    "Hello there, " 
    <span class="highlightYellow">how</span 
    " are you today" 
</p> 
+0

なぜこの点が重要ですか?あなたは特定の構造に依存する他のコードを持っていますか? – bernie

+0

はい、あります。私はここにあるコード(http://home.arcor.de/martin.honnen/javascript/storingSelection1.html)を使用して、テキストの選択を保存/復元するのを手伝っています。 DOM構造が変更されていないことが必要です。 – Jon

+0

おかげさまで、清算と幸運をありがとうございました – bernie

答えて

-5

これを使用してコンテンツをラップすることができます。

$(".highlightYellow").contents().unwrap(); 

デモ:http://jsfiddle.net/R4hfa/

+2

私はOPの質問を読んでいるので、スパンを削除する方法を尋ねていません。彼らは、スパンが追加されたときに分割されたテキストノードをどのように再構成するかを尋ねています。 – jfriend00

+0

私は理解したところから、彼はコンテンツの一部を強調して保存しています。そして、彼はそれを元に戻そうとすると、ハイライト(余分なスパンを追加した)のために修正されたコンテンツを取得します。 「スパンを挿入した後にDOM構造が分割されないようにするにはどうすればよいですか?」というテキストは、テキスト全体を 'span.highlightYellow'でラップしないと実行できません。代わりに、私の返信はこの「SPANタグを元の状態に戻した後、どのようにDOM構造を再構築するのですか?」という質問に答えます。 – codef0rmer

+0

あなたの質問は、挿入されたスパンタグを削除する方法に答えます。それが彼が求めていたものなら、あなたはそれを持っています。私は、テキストノードを、私が答えようとしたスパンタグの周りに分割される前の状態に戻す方法を尋ねていると思っていました。私達が同意するかもしれない1つのことは、この点でこの問題が完全にはっきりしていないということです。 – jfriend00

5

<span>タグを挿入する動作は、DOMを変更します。それは、定義によって、surroundContents()に電話をしたときのやり方です。テキストノードの分割やスパンの新しい要素の追加を含むDOMを変更せずにスパンタグを追加することはできません。

さらに、選択されたテキストにテキストノード全体のみが含まれていて、テキストノードの途中で選択が開始/停止しない場合は、テキストノードを分割して適切な場所に配置する必要があります。後でスパンタグを削除すると、追加のテキストノードが作成されます。それは本当に問題ではありませんが、分割されたテキストノードを元の状態に戻さなければならないと考えるなら、私はいくつかのオプションを考えることができます:

1)スパンの前に元のparentNodeを保存しますそれに挿入されます。クローンを作成し、クローンにスパンを追加し、元のノードをクローンと置き換えて元のファイルを保存します。復元する場合は、元のものを元に戻し、複製したものを削除します。

2)スパンを削除するときに、隣接するテキストノードを検索して結合する関数を実行します。

3)これは、前に比べてテキストノードが増えている理由を説明しています。なぜなら、これはコードや表示に関係しないからです。

+5

私はこれが古いと知っていますが、あなたの#3。これは、テキストノードに依存するプラグインの強調表示のために重要です。プラグインが、選択された要素のすべてのテキストノードをマッチの対象としている場合は、2つの隣接するテキストノード間で分割された一致を検出しません(以前の強調表示が元に戻された可能性があります)。 2つをマージするとその問題は解決されますが、ハイライトしているプラ​​グインはマッチを探している間にそれを行うことができると思います。 –

+5

#2に関するコメントを追加したいだけです。これを行うDOMメソッドがあります:[normalize()](https://developer.mozilla.org/en-US/docs/DOM/Node.normalize) – tcovo

+0

@tcovo - 面白いです。私はnormalize()について知りませんでした。知っておいてよかった。 – jfriend00

63

使用element.normalize()

挿入したスパンを削除した後に、element.normalize()メソッドを使用して、スパンの挿入/削除の結果として作成された余分なテキストノードをマージすることができます。 normalize()メソッドは、指定された要素とそのサブツリーのすべてを「正規化」形式にします(つまり、サブツリー内のテキストノードは空ではなく、隣接するテキストノードもありません)。 @ tcovoのコメントのおかげで見つかりました。

ノードを挿入して削除すると、要素内のテキストノードが分割されます。残念ながら、余分なノードが削除されると自動的には再マージされません。 "なぜ"この問題が起こっているかに関して人々の質問に答えるために、UIでのテキストハイライトを扱うときに問題が発生します。

+1

そのヒントありがとう! – silkAdmin

+3

おかげで、ありがとう!私は2時間探しています。 'normalize()'は、jQueryオブジェクトではなくDOM要素で呼び出される必要があることに注意してください。 '$( 'section.scope p')[0] .normalize();' – Archonic

+11

のようなjQueryセレクタ配列の最初のオブジェクトを選択する必要があります。 – shankardevy

1

normalize()ご注意ください! <br/>のようなノードを削除し、テキストとその視覚化を変更します。

normalize()ですが、欠点があります。

ので<p>"this is an "<br/>"example"</p>normalize()が、<br/> Sを保つを使用する方法はあり<p>this is an example</p>

に変わるのでしょうか?

関連する問題