代码和特性在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. 数据库安全性操作——操作原则及SQL注入

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6893134.html 今天在进行支付宝开发时,看到支付宝开发文档<开放平台第三方应用安全开发指南> ...

  2. Vue之Vuex

    一.什么是vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.简单来说就是一个数据统一 ...

  3. SparkR安装部署及数据分析实例

    1. SparkR的安装配置 1.1.       R与Rstudio的安装 1.1.1.           R的安装 我们的工作环境都是在Ubuntu下操作的,所以只介绍Ubuntu下安装R的方法 ...

  4. opcache开启前后性能对比

    opcache PHP新的字节码缓存扩展 字节码缓存组件 Zend Optimizer+ 现在更改名字为 Zend opcache了.且在php 5.5版本后,会集成到php的官方组件中,也就没有必要 ...

  5. java(5)循坏结构

    一. while循环 1.循环的优点? 减少重复代码的编写:程序会更加的简洁 2.语法 while(表达式){ // 1.表达式是[循环条件],结果必须是boolean类型 //2.{}中的代码,即[ ...

  6. java原生实现屏幕设备遍历和屏幕采集(捕获)等功能

    前言:本章中屏幕捕获使用原生java实现,屏幕图像显示采用javacv1.3的CanvasFrame 一.实现的功能 1.屏幕设备遍历 2.本地屏幕图像采集(也叫屏幕图像捕获) 3.播放本地图像(采用 ...

  7. datatables 学习笔记1 基础篇

    本文共3部分:基本使用|遇到的问题|属性表 1.DataTables的默认配置 $(document).ready(function() { $('#example').dataTable(); } ...

  8. [翻译]怎么写一个React组件库(二)

    本文同步发布于知乎专栏 https://zhuanlan.zhihu.com/p/27434018,喜欢本文的就去知乎点个赞支持下吧- 引言 该系列文章将通过创建一个组件库来引导你学习如何构建自己的组 ...

  9. iptables 基本用法

    iptables 1.iptables 表 (1)介绍常用表 filtert(过滤器) 链 ↓ INPUT chain:控制进入主机的数据包 OUTPUT chain:控制向外发出的数据包 FORWA ...

  10. web存储之webstorage

    web存储分类 客户端和服务端 认识web存储 随着web应用的发展,是的客户端存储的用途越来越多,然而实现客户端端存储的方式也是越来越多样化.最简单最兼容的方式就是cookie,但作为真正的客户端存 ...