2011-12-08 40 views
2

突出HTML我開發使用UIWebView iOS版電子書閱讀器。目前我正在處理一些基本的HTML文件,但最終會與ePub一起工作。我正在尋找一種適合文本範圍的樣式。我的範圍有點特別,因爲它們通常包含三個範圍 - 緊接在之前和之後的範圍和範圍。鍵範圍可以跨越多個節點,並且可以例如在粗體文本的選擇內開始或結束等。樣式不應被寫入文件。任何替代使用的execCommand在iOS版電子書閱讀器

目前,我有一個工作的解決方案如下:

document.designMode = "on"; 

// Color the first section 
var selection = window.getSelection(); 
selection.removeAllRanges(); 
selection.addRange(range1); 

if (!selection.isCollapsed){ 
document.execCommand("foreColor", false, color1);  
} 

// Color the middle section 
selection.removeAllRanges(); 
selection.addRange(range2); 

if (!selection.isCollapsed){ 
document.execCommand("backColor", false, color2); 
document.execCommand("foreColor", false, color3); 
} 

// Color the last section 
selection.removeAllRanges(); 
selection.addRange(range3); 

if (!selection.isCollapsed){ 
document.execCommand("foreColor", false, color1); 
} 

document.designMode = "off"; 
selection.removeAllRanges(); 

這工作得很好,但明顯慢(上一個iPad2),即使我修改它突出一個簡短的HTML文檔中的單個範圍。在文本被風格化之前總會有一個非常明顯的延遲。看着iPad上的電子書閱讀器,如kindle或iBooks,沒有明顯的延遲。他們如何實現他們的突出功能?他們可能會閱讀所選文本的地理位置並應用某種疊加?比我已經使用,但沒有運氣,所以如果任何人有一個想法,我將非常感激我已經尋找一個更好的解決方案

謝謝!

回答

8

我已到上述顯示要快得多的替代方法。它主要基於mikeB在這個問題中給出的優秀代碼。

How to get nodes lying inside a range with javascript?

  1. 我第一次分裂與 僅與給定的範圍落在文本創建新文本節點開始和結束的節點。我調整了新節點的範圍 。

  2. 我使用上述鏈接的代碼的稍微修改版本 返回範圍內包含的text nodes的數組。通過陣列

  3. 我循環,把跨度周圍每個文本 節點樣式。

據我測試的代碼效果很好。同時將樣式應用於多個範圍時,仍然存在延遲,但比以前好得多。我很想知道是否有人有任何改進。

我的代碼:

function styleRange(range, style) // the style is a string of css styles. eg."background-color:darkblue; color:blue;" 
{  
    // Get the start and end nodes and split them to give new start and end nodes with only text that falls inside the range. 
    var startNode = range.startContainer.splitText(range.startOffset); 
    var endNode = range.endContainer.splitText(range.endOffset).previousSibling; 

    // Adjust the range to contain the new start and end nodes 
    // The offsets are not really important anymore but might as well set them correctly 
    range.setStart(startNode,0); 
    range.setEnd(endNode,endNode.length); 

    // Get an array of all text nodes within the range 
    var nodes = getNodesInRange(range); 

    // Place span tags with style around each textnode 
    for (i = 0; i < nodes.length; i++) 
    { 
     var span = document.createElement('span'); 
     span.setAttribute("style", style); 
     span.appendChild(document.createTextNode(nodes[i].nodeValue)); 
     nodes[i].parentNode.replaceChild(span, nodes[i]); 
    } 
} 
從mikeB的代碼

修改後的代碼:

function getNodesInRange(range) 
{ 
    var start = range.startContainer; 
    var end = range.endContainer; 
    var commonAncestor = range.commonAncestorContainer; 
    var nodes = []; 
    var node; 

    // walk parent nodes from start to common ancestor 
    for (node = start.parentNode; node; node = node.parentNode) 
    { 
     if (node.nodeType == 3) //modified to only add text nodes to the array 
      nodes.push(node); 
     if (node == commonAncestor) 
      break; 
    } 
    nodes.reverse(); 

    // walk children and siblings from start until end is found 
    for (node = start; node; node = getNextNode(node)) 
    { 
     if (node.nodeType == 3) //modified to only add text nodes to the array 
      nodes.push(node); 
     if (node == end) 
      break; 
    } 

    return nodes; 
} 


function getNextNode(node, end) 
{ 
    if (node.firstChild) 
     return node.firstChild; 
    while (node) 
    { 
     if (node.nextSibling) 
      return node.nextSibling; 
     node = node.parentNode; 
    } 
} 
+0

在這裏,我創建的EPUB閱讀器應用程序的iPad應用程序,在這裏我只是解壓縮並加載EPUB在UIwebview我試圖突出顯示並使用uimenuviewcontroller在uiwebview中添加註釋,我選中了文本並使用execommand或窗口獲取文本,但是我的疑問是如何存儲並重新註釋該註釋並突出顯示webview中的文本,請您幫助我 – dineshprasanna

+0

有沒有辦法切換?所以當用戶第二次將範圍設置爲「粗體」時,它實際上會刪除粗體樣式? – Apollo

0

阿波羅爲了取得成功,你必須在創建範圍,通過傳遞來設置一個onclick監聽器回撥功能,如

span.addEventListener("click",callbackwhenclickeventtrigger,false); 
function callbackwhenclickeventtrigger(e){//pass as param the event target, inside this function create the un-bold function 
} 
相關問題