ここに記事を書きました。
基本的に、私がやりたいことは、コンテンツ編集可能領域の DIV の前の要素を選択することです。私は理解できない行動に出くわし、これが「うまくいくはず」なのか疑問に思っています。
次のマークアップを検討してください。
<DIV contenteditable="true">foo<div id="test">bar</div></div>
前の要素を選択したい<div id="test">
。
だから私は使用します:
var sel = document.getSelection();
var range = document.createRange();
var dom_node = document.getElementById( 'test' );
// this is the critical method
range.setStartBefore( dom_node );
range.collapse( true );
sel.removeAllRanges();
sel.addRange( range );
console.log( "selection is :", document.getSelection().getRangeAt(0) );
(残念ながら、jsfiddle.netがjsfiddleエラーを生成するため、これを試してみると、ここの静的ページに掲載しました)
私が取得している範囲は、FireFox と Chrome で大きく異なります。
Chrome は、startOffset が 3 の textnode の startContainer を返します。これは、テキスト「foo」のすぐ後ろを適切に指しています。これは私が期待するものです。その位置にカーソルが移動します。
FireFox は、編集可能な DIV の startContainer をオフセット 1 で返し、textnode 全体を指します。私が期待するものではありません。カーソル (div にフォーカスがある場合) は、'bar' のすぐ左を指します。
HTML が次のように変更されると、より奇妙になります。
<DIV contenteditable="true"><div>foo</div><div id="test">bar</div></div>
実験を繰り返すと、FireFox は編集可能な DIV と 1 の startOffset を持つ startContainer を返します。カーソルは「bar」の前に残ります。前回のテストの結果を考えると、これは理にかなっています。
ただし、Chrome は、長さが 0 の textnode と nextSibling previousSibling を含む startContainer を返します。どちらも null ですが、parentNode は div id="test" に設定されています。カーソルは「バー」の前に残ります。
これは正しい動作ですか?このような範囲を取得したとき、あなたは何をすることになっていますか?それとも setStartBefore()/After() が壊れていますか?