当前位置:  开发笔记 > 编程语言 > 正文

在iOS电子书阅读器中使用execCommand突出显示HTML的任何替代方法

如何解决《在iOS电子书阅读器中使用execCommand突出显示HTML的任何替代方法》经验,为你挑选了1个好方法。

我正在为iOS开发一个图书阅读器UIWebView.目前我正在使用一些基本的HTML文件,但最终将与ePubs一起使用.我正在寻找一种合适的文本范围样式.我的范围有点特殊,因为它们通常包含三个范围 - 一个键范围和一个范围,紧接在之前和范围之后.键范围可以跨越多个节点,并且可以例如在粗体文本等的选择内开始或结束.不应将样式写入文件.

目前我有一个工作解决方案如下:

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,没有明显的延迟.他们如何实现突出显示功能?他们可能正在阅读所选文本的地理位置并应用某种叠加?

我已经找到了比我已经使用的更好的解决方案,但没有运气,所以如果有人有想法我会非常感激.

谢谢!



1> Simple99..:

我已经为上面做了一个替代方法,它看起来要快得多.它主要基于mikeB在这个问题中给出的优秀代码.

如何使用javascript获取位于范围内的节点?

    我首先分割开始节点和结束节点,创建新的文本节点,只包含符合给定范围的文本.我调整新节点的范围.

    我在上面的链接中使用稍微修改过的代码版本来返回text nodes包含在范围内的数组.

    我遍历数组并在每个文本节点周围放置样式.

据我测试,代码效果很好.当同时将样式应用于多个范围时,仍然会有延迟,但它比以前好多了.我有兴趣知道是否有人有任何改进.

我的代码:

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;
    }
}

推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有