2013-04-07 56 views
2

我正在尝试制作一个小文本编辑器。范围对象,获取选择父节点Chrome vs Firefox

当我选择一个文本,我想知道如果选中的文本是独自在spandiv,那么我想改变这个元素的风格。

例子:

<span style="font-size:12px">Hola</span> 

如果我选择HOLA我要检索的父节点<span style="font-size:12px">Hola</span>

<span style="font-size:56px"> 
Hola <span style="font-size:12px">Hello</span> 
</span> 

如果我选择你好我只想检索<span style="font-size:12px">Hello</span>

现在,当我尝试使用Chrome时,我得到了合作伙伴rrect与

range.startContainer.parentNode; 

但与Firefox导致第二个例子我找回

<span style="font-size:56px"> 
    Hola <span style="font-size:12px">Hello</span> 
</span> 

我怎样才能在Chrome和Firefox中相同的结果?

回答

8

您的问题是,当选择边界中的一个或两个选择边界与DOM节点边界一致时,浏览器之间的选择工作略有不同。例如,如果用户选择了网页内容的单词“酒吧”与下面的HTML

<p>foo<i>bar</i></p> 

...有供选择四种不同的可能位置开始,所有看起来视觉上相同的用户:

  1. 在“foo”的文本节点的端部(节点“foo”的,偏移3)
  2. <p>元件的一个子节点之后(节点<p>,偏移量1)
  3. <i>的零名儿童元素(节点<i>,偏移量为0)
  4. 在“栏中的”文本节点(节点“栏”字索引0,偏移0)

大多数浏览器不允许在实践中,所有这些位置,但不幸的是不同的浏览器做不同的选择。在Firefox中,您所做的选择选择整个<span>元素,而选择范围的startContainer<span>的父节点。你可以通过检查的范围内检测到这个,看看它是否选择一个节点:

function rangeSelectsSingleNode(range) { 
    var startNode = range.startContainer; 
    return startNode === range.endContainer && 
      startNode.hasChildNodes() && 
      range.endOffset === range.startOffset + 1; 
} 

你可以用它来检测你有什么样的选择,并据此获得所选择的元素:

var selectedElement = null; 
if (rangeSelectsSingleNode(range)) { 
    // Selection encompasses a single element 
    selectedElement = range.startContainer.childNodes[range.startOffset]; 
} else if (range.startContainer.nodeType === 3) { 
    // Selection range starts inside a text node, so get its parent 
    selectedElement = range.startContainer.parentNode; 
} else { 
    // Selection starts inside an element 
    selectedElement = range.startContainer; 
} 
+0

谢谢!!!!这是完美的!!! – 2013-04-10 23:27:15

+0

在Chrome中完美呈现 – 2015-08-30 13:45:08