2013-04-07 28 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