2

次の DOM ツリーを想定します。

<div id="edit" contenteditable="true">
  this content <a id="link" href="http://www.google.com/">contains</a> a link
</div>

次に、アンカーの直後に範囲を作成します。

var r = document.createRange();
var link = document.getElementById('link');
r.setStartAfter(link);
r.setEndAfter(link);

予想通り、それcommonAncestorContainerは id を持つ要素editです:

console.log(r.commonAncestorContainer);  /* => <div id="edit" contenteditable="true">…&lt;/div> */

選択範囲を次の範囲に設定します。

var s = window.getSelection();
s.removeAllRanges();
s.addRange(r);

ウィンドウに現在の選択範囲を照会し、その範囲を確認しますcommonAncestorContainer

var r2 = s.getRangeAt(0);
console.log(r2.commonAncestorContainer);

Firefox では、期待どおりの結果が得られることがわかります。id を持つ同じ要素edit

ただし、WebKit ブラウザーでは、選択範囲の祖先コンテナーが突然、アンカー内のテキスト ノードになります。"contains"ですが、入力を開始すると、実際にはアンカーの内側にいないことがわかります。なんと!?

ライブデモについては、ここをクリックしてください

この動作の背後に潜在的な理由はありますか? WebKit のバグではないと仮定する理由はありますか??

$.02 ありがとうございます。

4

1 に答える 1

1

WebKit では、DOM 内の特定の位置のみを選択境界またはキャレット位置として使用できます。したがって、選択のaddRange()メソッドを使用して選択された範囲を、これに準拠するように変更します。https://stackoverflow.com/a/14104166/96100も参照してください。

別の問題があります。WebKit には、リンクの末尾にあるキャレット位置の特殊なケースがあり、その位置に入力されたテキストがリンク内ではなくリンクの後に配置されるということです。ブラウザーが選択範囲がリンク内にあると報告することを考えると、これは紛れもなく厄介なハックです。ただし、この変更されたバージョンのデモで確認できるように、これは他のインライン要素では発生しません。

http://jsbin.com/EYoWuWe/7/edit

于 2013-09-03T15:02:24.983 に答える