2011-10-07 84 views
5

樂代碼: http://jsfiddle.net/frf7w/12/Javascript:如何根據html標籤擴展用戶選擇?

所以現在,當前的方法將正好把選定的文本爲...選擇,添加標籤,這樣在顯示時,頁面不炸燬。

但我想要做的是: 是,當用戶選擇頁面的一部分時,如果選擇內有不匹配的標籤,選擇將向前或向後跳轉(取決於不匹配的標籤在選擇中)到使選擇有效的html的標籤。

我想這樣做的原因是因爲我希望用戶能夠在頁面上選擇文本,並且能夠在所見即所得編輯器中編輯該文本(我目前可以通過鏈接的代碼執行此操作),然後將他們編輯的內容放回頁面中(目前不能這樣做,因爲我使用的方法添加了標籤)。

+0

我看到你在你的選擇中添加一個div,一旦添加,你認爲你可以得到這個div的父母,然後選擇它?但是,最終可能會出現奇怪的行爲。 – boulaycote

+0

該div僅用於顯示選定的文本。選定的文本本身沒有添加div。 = \ – NullVoxPopuli

+0

因此,選擇該div的父級,可能會選擇整個頁面。 – NullVoxPopuli

回答

2

您可以通過adding a range改變選擇的邊界:

var sel = window.getSelection(), 
    range = sel.getRangeAt(0); 

var startEl = sel.anchorNode; 
if (startEl != range.commonAncestorContainer) { 
    while (startEl.parentNode != range.commonAncestorContainer) { 
     startEl = startEl.parentNode; 
    } 
} 
var endEl = sel.focusNode; 
if (endEl != range.commonAncestorContainer) { 
    while (endEl.parentNode != range.commonAncestorContainer) { 
     endEl = endEl.parentNode; 
    } 
} 

range.setStartBefore(startEl); 
range.setEndAfter(endEl); 

sel.addRange(range); 

上面的例子會給你擴展到涵蓋選擇包括開始和結束節點之間的整個樹(包括commonAncestorContainer())。

這將文本節點視爲等同於dom元素,但這不應該成爲您的問題。

演示:http://jsfiddle.net/Nq6hr/2/

+0

是這個跨瀏覽器,如IE7 +,然後真正的瀏覽器? – NullVoxPopuli

+1

我已經在Chrome 14,FF7,IE9中測試過。我認爲IE只支持版本9 – Deebster

+0

的'range'對象。會給我一個藉口給我的老闆另一個理由建議我們的客戶升級= D – NullVoxPopuli

3

在此SO答案的coverAll方法有你想要Use javascript to extend a DOM Range to cover partially selected nodes什麼。出於某種原因,延伸Selection原型在我的鉻合金上不適用於我,因此我提取了代碼並用window.getSelection()代替this。最終代碼如下所示:

function coverAll() { 
    var ranges = []; 
    for(var i=0; i<window.getSelection().rangeCount; i++) { 
     var range = window.getSelection().getRangeAt(i); 
     while(range.startContainer.nodeType == 3 
       || range.startContainer.childNodes.length == 1) 
      range.setStartBefore(range.startContainer); 
     while(range.endContainer.nodeType == 3 
       || range.endContainer.childNodes.length == 1) 
      range.setEndAfter(range.endContainer); 
     ranges.push(range); 
    } 
    window.getSelection().removeAllRanges(); 
    for(var i=0; i<ranges.length; i++) { 
     window.getSelection().addRange(ranges[i]); 
    } 
    return; 
}