1

これが私のHTMLです:

<ul contenteditable>
  <li>Hi there 1</li>
  <li>HI 2 2 2 2 2</li>
  <ul><li>hi 3</li></ul> <!-- I know it's invalid, it's what document.execCommand('indent') yields -->
  <li> hi 4 hi there people 4 here now </li>
</ul>

(来週はhttp://www.webdevout.net/test?06&rawで見ることができます)

現在選択されているテキスト(IE8)が1つのLI内にあるのか、複数のLIにまたがっているのかを判断しようとしています。LIの1と2全体を選択し、コンソールに次のように入力すると、2番目のLI(HI 2 2 2 2 2 2)のみdocument.selection.createRange().parentElement().innerHTMLの内容が返されます。

TextRange.parentElementが範囲全体の親ではなく、範囲の最後の要素を返すのはなぜですか?

ドキュメントには、「テキスト範囲が複数の要素のテキストにまたがる場合、このメソッドはすべての要素を囲む最小の要素を返します」と書かれています。私の最終的な目標は、複数のLIが選択されているかどうかを判断することです。「parentElement()。nodeName.toUppercase === "LI"」で実行できるかどうかを確認しましたが、parentElement()がparentElementを返さない場合は実行できません。

4

1 に答える 1

3

私は以前にこの種のことを見たことがあり、それはIEのバグです。Rangyライブラリで使用する回避策は、次の3つの要素の最も内側の共通の祖先を使用することです。

  • parentElement()TextRangeの
  • 折りたたみ(true)を呼び出した後のparentElement()TextRangeの
  • 折りたたみ(false)を呼び出した後のparentElement()TextRangeの

Rangyのコードは次のとおりです。

/*
 This is a workaround for a bug where IE returns the wrong container
 element from the TextRange's parentElement() method. For example,
 in the following (where pipes denote the selection boundaries):

 <ul id="ul"><li id="a">| a </li><li id="b"> b |</li></ul>

 var range = document.selection.createRange();
 alert(range.parentElement().id); // Should alert "ul" but alerts "b"

 This method returns the common ancestor node of the following:
 - the parentElement() of the textRange
 - the parentElement() of the textRange after calling collapse(true)
 - the parentElement() of the textRange after calling collapse(false)
 */
var getTextRangeContainerElement = function(textRange) {
    var parentEl = textRange.parentElement();

    var range = textRange.duplicate();
    range.collapse(true);
    var startEl = range.parentElement();

    range = textRange.duplicate();
    range.collapse(false);
    var endEl = range.parentElement();

    var startEndContainer = (startEl == endEl) ?
        startEl : dom.getCommonAncestor(startEl, endEl);

    return startEndContainer == parentEl ?
        startEndContainer : dom.getCommonAncestor(parentEl, startEndContainer);
};
于 2012-07-30T23:57:36.497 に答える