在 iOS 电子书阅读器中使用 execCommand 突出显示 HTML 的任何替代方法
Posted
技术标签:
【中文标题】在 iOS 电子书阅读器中使用 execCommand 突出显示 HTML 的任何替代方法【英文标题】:Any alternative to using execCommand for Highlighting HTML in iOS ebook reader 【发布时间】:2012-01-15 18:56:27 【问题描述】:我正在使用 UIWebView
为 ios 开发图书阅读器。目前我正在使用一些基本的 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();
即使我修改它以突出显示简短 HTML 文档中的单个范围,它也可以正常工作,但速度很慢(在 iPad2 上)。在对文本进行风格化之前,总会有一个非常明显的延迟。在 iPad 上查看电子书阅读器(例如 kindle 或 iBooks)没有明显的延迟。他们如何实现高亮功能?他们可能正在阅读所选文本上的地理位置并应用某种叠加层吗?
我已经寻找了比我已经使用的更好的解决方案,但没有运气,所以如果有人有想法,我将非常感激。
谢谢!
【问题讨论】:
【参考方案1】:我已经做了一种替代方法,看起来要快得多。主要是基于mikeB在这个问题中给出的优秀代码。
How to get nodes lying inside a range with javascript?
我首先拆分开始和结束节点,创建新的文本节点 只有落在给定范围内的文本。我调整范围 用于新节点。
我在上面的链接中使用了稍微修改过的代码版本
返回包含在范围内的text nodes
数组。
我循环遍历数组并在每个文本周围放置带有样式的 span 节点。
据我测试,代码运行良好。当同时将样式应用于多个范围时,仍然存在延迟,但比以前好得多。我很想知道是否有人有任何改进。
我的代码:
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;
【讨论】:
这里我正在为 ipad 应用程序创建 epub 阅读器应用程序,这里我只是在 uiwebview 中解压缩并加载 epub,我尝试使用 uimenuviewcontroller 在 uiwebview 中突出显示和添加注释,我选择了文本并获取使用 execommand 或窗口的文本,但我的疑问是我如何存储和检索注释并在 webview 中突出显示文本,您能帮帮我吗 有没有办法切换?那么当用户第二次设置“粗体”范围时,它实际上会移除粗体样式?【参考方案2】:为了让 Apollo 成功,您必须在创建 span 时设置一个 onclick 监听器,方法是传递一个回调函数,例如
span.addEventListener("click",callbackwhenclickeventtrigger,false);
function callbackwhenclickeventtrigger(e)//pass as param the event target, inside this function create the un-bold function
【讨论】:
以上是关于在 iOS 电子书阅读器中使用 execCommand 突出显示 HTML 的任何替代方法的主要内容,如果未能解决你的问题,请参考以下文章
使用 Parse.com 通过 iOS 应用创建新用户时发送电子邮件
iOS 上的 GMail 应用程序使用啥来编辑 HTML 电子邮件?