代码和特性在chrome49下测试有效。

文本渲染的本质是对文本节点的渲染,通过浏览器内置的对象Range可以获得选择的起始点、与终止点

 

var range = getRangeObject();
var start = range.startOffset,
end = range.endOffset;
var startContainer = range.startContainer;
var endContainer = range.endContainer;

getRangeObjec代码如下

function getRangeObject(){

if(window.getSelection)
{
var selection = window.getSelection();
if(selection.rangeCount > 0)
{
return selection.getRangeAt(0);
}
}
else if(document.selection)
{
return document.selection.createRange();
}
return null;
};

  起始点始终在左面,终止点始终在右面,不受选择方向的影响。
  只有当起始点的开头或终止点的末尾是<br/>时,返回的不是文本节点,可以通过start,end确定br元素的位置分别是startContainer.childNodes[start],endContainer.childNodes[end-1]。返回的是文本节点start表示光标相对于起始文本节点所在的起始位置,end表示光标相对于终止文本节点所在的终止位置。

获得下一个文本节点的算法为

function getNextTextNode(startNode,dir = "nextSibling"){
//记录startNode变化之前的状态,startNode变化后无效时便于状态的回滚
let unchangeNode = startNode;
if(startNode.nodeType == 3){
startNode = startNode[dir];
}
while (true){ if(startNode == undefined){
if(unchangeNode == undefined){
//保护机制
throw new Error("程序会陷入死循环");
break;
}
/*
startNode所在的父元素所有选中节点遍历完毕,将sartNode指向父元素的兄弟节点
*/
let parent = unchangeNode.parentElement;
unchangeNode = parent;
startNode = parent[dir];
}
else if(startNode.nodeType == 3){
//文本节点则退出循环
break;
}
else if(startNode.tagName == "BR"){
//处理单标签,避免不必要的迭代
unchangeNode = startNode;
startNode = startNode[dir];
}
else if(startNode.nodeType == 1){
/*
如果是双标签元素则进入
*/
unchangeNode = startNode; if(dir == "previousSibling"){ startNode = $(startNode).contents().last().get(0);
}
else if(dir == "nextSibling"){
startNode = $(startNode).contents().first().get(0);
}
else {
//便于错误的定位
throw new Error("错误的遍历方向:"+dir);
}
}
else {
//便于错误的定位
throw new Error("不期待的元素类型=》"+startNode); }
} return startNode; }

  //上述函数用外部变量+while循环的方式取代递归,加入的保护机制减少误用、潜在bug导致极差的体验。
获得起始节点和结束节点之间的所有文本节点

function getTextNodes(startTextNode,endTextNode){
let textNodeArray = [];
let node = startTextNode;
while (true) {
node = getNextTextNode(node); if(node == endTextNode){
break;
}
textNodeArray.push(node);
} return textNodeArray; }

赞赏支持

H5编辑器核心算法和思想-遁地龙卷风的更多相关文章

  1. Unity3D_(游戏)甜品消消乐02_游戏核心算法

    甜品消消乐01_游戏基础界面 传送门 甜品消消乐02_游戏核心算法 传送门 甜品消消乐03_游戏UI设计    传送门 GameManager脚本上修改Fill Time可以改变消消乐移动速度 实现过 ...

  2. jquery toggle方法使用出错?请看这里-遁地龙卷风

    这个函数在1.9之前和1.9之后的用法大不相同 1 1.9之间,用于点击元素时函数的轮流执行 toggle(function() { alert(1);//1,3,5,7... },function( ...

  3. 逻辑思维面试题-java后端面试-遁地龙卷风

    (-1)写在前面 最近参加了一次面试,对笔试题很感兴趣,就回来百度一下.通过对这些题目的思考让我想起了建模中的关联,感觉这些题如果没接触就是从0到1,考验逻辑思维的话从1到100会更好,并且编程简易模 ...

  4. JQuery data方法的使用-遁地龙卷风

    (-1)说明 我用的是chrome49,这个方法涉及到JQuery版本问题,我手里有3.0的,有1.9.1,后面将1.9.1及其以前的称为低版本,3.0称为高版本 测试例子用到的showMessage ...

  5. JQuery simpleModal插件的使用-遁地龙卷风

    (0)写在前面 jquery.simpleModal.浏览器这三者的兼容性,不仅显示在报错上,还体现在所呈现的效果不是预期上. 说一下我的环境 jquery-1.8.3.js jquery.simpl ...

  6. SQL关键字转换大写核心算法实现

    1 不跟你多废话 上代码! /// <summary> /// SQL关键字转换器 /// </summary> public class SqlConverter : IKe ...

  7. 用Java实现MVPtree——MVPtree核心算法代码的搭建

    项目需要,需要把MVPtree这种冷门的数据结构写入Java,然网上没有成形的Java实现,虽说C++看惯了不过对C++实现复杂结构也是看得蒙蔽,幸好客户给了个github上job什么的人用Java写 ...

  8. x264代码剖析(十三):核心算法之帧间预測函数x264_mb_analyse_inter_*()

    x264代码剖析(十三):核心算法之帧间预測函数x264_mb_analyse_inter_*() 帧间预測是指利用视频时间域相关性,使用临近已编码图像像素预測当前图像的像素,以达到有效去除视频时域冗 ...

  9. x264代码剖析(十五):核心算法之宏块编码中的变换编码

    x264代码剖析(十五):核心算法之宏块编码中的变换编码 为了进一步节省图像的传输码率.须要对图像进行压缩,通常採用变换编码及量化来消除图像中的相关性以降低图像编码的动态范围.本文主要介绍变换编码的相 ...

随机推荐

  1. html学习笔记 - 列表

    <!-- 无序列表 --> <ul type = square> <li><a href="https://www.baidu.com"& ...

  2. 点击空白处隐藏指定dom元素(纯javascript方法)

    <script type="text/javascript"> document.onclick = function (event) { event = event ...

  3. Hash Table Performance in R: Part I(转)

    What Is It? A hash table, or associative array, is a well known key-value data structure. In R there ...

  4. 默认路由、RIPv2、OSPF、EIGRP配置(全网全通)

    1:默认路由 遇到问题:给r2配置向右的单项默认路由,通过PC1去ping主机PC2,一直显示Request timed out, 解决方法:r2配置如下: r2(config)#ip route 0 ...

  5. 利用 MUI开发app, 如何实现侧滑菜单及其主体部分上下滑动

     利用mui开发APP 之侧滑菜单主内容滚动问题 MUI作为开发者常用的框架之一,其号称最接近原生APP体验的高性能前端框架.因此利用mui开发移动APP,可以为开发者提供很大的便利和接近原生的体验. ...

  6. 目前微信 微博 新浪 豆瓣等所有分享的js插件

    原理 功能 集成微信.微博.开心.豆瓣.人人.qq微博.搜狐.qq空间等分享 即时分享: 默认加载插件,即启动全部分享 定制分享:通过参数配置.静态数据配置 由你决定何时分享,如何分享 扩展: 通过数 ...

  7. jQuery插件 -- 图片随页面滚动fixed

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. nodejs集成sqlite

    正在物色node上面的轻量级嵌入式数据库,作为嵌入式数据库的代表,sqlite无疑是个理想的选择方案.npm上集成sqlite的库主要有两个——sqlite3和realm. realm是一个理想的选择 ...

  9. Java学习之J2EE

    什么是J2EE  本文摘抄于其他博文. 什么是J2EE 一.准备篇 1 什么是J2EE?它和普通的Java有什么不同?答:J2EE全称为Java2 Platform Enterprise Editio ...

  10. 泛型(java菜鸟的课堂笔记)

                1. 泛型的简单运 用和意义   2. 泛型的上限与下限   3. 泛型和 子类继承的限制   4. 泛型类和泛型 方法   5. 泛型嵌套和泛型擦除             ...