这是我的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&下周的原料)
我正在尝试确定当前选择的文本(在IE8中)是在一个LI内还是跨越多个LI。当我选择LI的一和二的全部,然后在控制台document.selection.createRange().parentElement().innerHTML
中输入以下内容时,的内容只返回第二个LI(HI 2 2 2 2)。
为什么TextRange.parentElement返回范围中的最后一个元素,而不是整个范围的父元素
文档说:"如果文本范围跨越多个元素中的文本,则此方法返回包含所有元素的最小元素。"我的最终目标是确定是否选择了多个LI;我想"检查parentElement().nodeName.toUppercase==="LI"是否会这样做,但如果parentElements()没有返回parentElement,我就做不到。
我以前见过这种事情,它是IE中的一个错误。我在Rangy库中使用的解决方法是使用三个元素的最内部公共祖先:
- TextRange的
parentElement()
- 调用collapse后TextRange的
parentElement()
(true) - 调用collapse后TextRange的
parentElement()
(false)
这是来自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);
};