在iOS电子书阅读器中使用execCommand突出显示HTML的任何替代方法
我正在使用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();
这工作正常但速度明显很慢(在iPad2上),即使我修改它以突出显示短HTML文档中的单个范围。 在文本风格化之前总是存在非常明显的延迟。 看看iPad上的电子书阅读器,例如kindle或iBooks,没有明显的延迟。 他们如何实现突出显示function? 他们可能正在阅读所选文本的地理位置并应用某种叠加?
我已经找到了比我已经使用的更好的解决方案,但没有运气,所以如果有人有想法我会非常感激。
谢谢!
我已经为上面做了一个替代方法,它看起来要快得多。 它主要基于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; } }
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 }
- 在ViewControllers的iOS 7中使用JavaScriptCore从JavaScript触发目标C方法
- “alert()”和“confirm()”不支持“apple-mobile-web-app-capable”
- 图像正在下载铬,但不是在Safari浏览器
- 创build一个链接,启动iOS应用程序,或redirect到应用程序商店
- React Native中的React导航和导航器简介
- 使用Navigator推送新路线时出现问题
- iOS PhoneGapdebugging工作stream程
- UI自动化:访问UIScrollView中的UIViews
- 反应本机应用程序的UI(在iOS上)滞后,fps率定期下降