2011-12-08 32 views
2

UIWebViewを使用してiOS用ブックリーダーを開発しています。現時点では、いくつかの基本的なHTMLファイルを扱っていますが、最終的にはePubで動作します。私はテキストの範囲をスタイリングするのに適した方法を探しています。私の範囲は通常、3つの範囲(キーレンジと直前の範囲と直後の範囲)を含むという点で少し特殊です。キーレンジは、複数のノードに及ぶことがあり、例えば太字のテキストの選択などで開始または終了することができる。スタイリングはファイルに書き込まれてはならない。次のように私が働いて解決策を持っている瞬間 iOS電子ブックリーダーでHTMLを強調表示するためにexecCommandを使用する代わりの方法

:これは私が短いHTMLドキュメント内の単一の範囲をハイライト表示するように変更しても、正常に動作しますが、(iPad2の上)著しく遅い
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(); 

。テキストが定型化される前に、常に目立つ遅延があります。 kindleやiBooksのようなiPadの電子ブックリーダーを見ると、目に見える遅延はありません。ハイライト機能をどのように実装するのですか?選択されたテキストの地理的位置を読んで、何らかのオーバーレイを適用している可能性がありますか?

私はすでに使用しているよりも優れたソリューションを探していますが、運がないので、誰かがアイデアを持っていれば非常に感謝しています。

ありがとうございました!

答えて

8

私はずっと速く見える上記の代替方法を作った。これは主に、この質問で与えられたmikeBの優れたコードに基づいています。

How to get nodes lying inside a range with javascript?

  1. Iは、第一所定の範囲で低下 テキストのみを使用して新しいテキストノードを作成し、開始と終了ノードを分割します。私は新しいノードの範囲を に調整します。

  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

私はipadアプリのためのepubリーダーアプリを作成しています、ここで私はunzipとuiwebview私はuimenuviewcontrollerを使ってuiwebviewでメモを追加しようとしましたが、テキストを取得して、execommandまたはwindowを使ってテキストを取得しましたが、私の疑問はどうやってメモを保存して反復することができ、webviewのテキストをハイライトすることができます – dineshprasanna

+0

トグルする方法はありますか?だから、ユーザーが実際に大胆なスタイリングを取り除く2度目に "太字"の範囲をスタイルするとき? – 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 
} 
関連する問題