代码和特性在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;
}登录后复制
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!
相关教程推荐
- H5的canvas实现贪吃蛇小游戏
- 基于HTML5陀螺仪实现移动动画效果
- H5的服务器推送事件详解
- Canvas实现旋转风车的绘制
- mui的页面跳转方式
- phonegap播放音频详解
- H5添加语音输入功能
- H5的头部meta标签如何使用
- html5中重新加载音频/视频元素的方法load()
- HTML5的data-*自定义属性是什么
- Dreamweaver中设置html网页段落行间距的方法指导
- 带你了解什么是HTML5?
- HTML5canvas实现中奖转盘的实例代码
- 如何解决滚动条样式问题
- v-for怎么加载本地静态图片
- Vue.directive的自定义指令详解
- html如何定义错误提示
- HTML5设置视频背景的方法介绍
- html5是什么意思
- html5编辑器有哪些
其他课程推荐
- php添加pcntl多线程扩展(Linux)
- 做php的应该很多懂linux吧,问个有关问题,本地开发好后,怎么只把最近一天修改过的文件同步到服务器
- php linux解决方案
- imagegif函数linux下失败,windows下成功,为什么?解决思路
- linux下怎么安装php的扩展库
- Perl、PHP、Python、Ruby对于入门的Linux运维来说,哪个更易学?
- linux进程如图这两个进程是什么?占用资源挺多的
- linux下安装redis以及phpRedis扩展
- Cygwin下安装LinuxPHP环境和Swoole扩展并在PHPStorm中调试
- Linux下C++实现PHP扩展
- linuxphp5.3.x升级到php5.5.x
- 【Linux】LAMP架构之以模块方式让php和httpd搭档工作
- linux下vim实现php远程调试环境搭
- linux php fopen怎么打不开远程文件?
- PHP施行linux命令
- Linuxvi/vim编辑器
- linux系统目录介绍
- 为什么要学linux
- Linux
- Linux下MySQL出现#1036–Table‘‘isreadonly错误解决方法