区域可编辑contenteditable的问题总结
一、如何在可编辑区域div的光标处通过点击事件来添加文本内容
下面的例子是可编辑div的区域添加文本内容和判断光标位置的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
焦点位置:<input id="i1">选中文本:<input id="i2"> <div id="d1" contenteditable="true" style="width:200px;height:100px;border:1px solid black">1234567890abcdef
</div>
<button id="add">添加文字</button>
</body>
<script type="text/javascript">
add.onclick=function () {
var obj= d1;
var range, node;
if(!obj.hasfocus) {
obj.focus();
}
if (window.getSelection && window.getSelection().getRangeAt) {
range = window.getSelection().getRangeAt(0);
range.collapse(false);
node = range.createContextualFragment('10000ss');
var c = node.lastChild;
range.insertNode(node);
if(c){
range.setEndAfter(c);
range.setStartAfter(c)
}
var j = window.getSelection();
j.removeAllRanges(); range = window.getSelection().getRangeAt(0);
j.addRange(range); } else if (document.selection && document.selection.createRange) {
document.selection.createRange().pasteHTML(text);
}
}
document.onselectionchange = function (e) {
// ie11
//判断是否支持document.selection属性
if (document.selection) {
var pos = 0;
var range = document.selection.createRange();
var srcele = range.parentElement();
//新建一个range,焦点在开头
var copy = document.body.createTextRange();
copy.moveToElementText(srcele);
//判断copy的焦点起始部分是否在range的焦点起始部分的后面
for (pos = 0; copy.compareEndPoints("StartToStart", range) < 0; pos++) {
//copy的焦点向后移动一个字符
copy.moveStart("character", 1);
}
document.getElementById('i1').value = pos;
document.getElementById('i2').value = range.htmlText;
}
// chrome uc
if (window.getSelection) {
//获取Selection对象
var se = window.getSelection();
//获取起始位置,这个是字符的序号位置,而不是坐标
var start = se.anchorOffset;
//获取结束位置
var end = se.focusOffset;
//获取起始的dom元素
var startEl = se.anchorNode.parentElement;
//获取结束的dom元素
var endEl = se.focusNode.parentElement;
//获取起始dom元素的文本内容
var startText = startEl.innerText;
var txt = '';
if (startEl == endEl) {
txt = startText.substring(start, end);
} document.getElementById('i1').value = start;
document.getElementById('i2').value = txt;
}
} </script>
</html>
range.startOffset;相对于上个元素
获取整个元素偏移量的方法(复制的情况需要自己来计算)
var range = window.getSelection().getRangeAt(0);
var offset = 0;
var str = '';
var container = range.endContainer;
console.log(container)
var i=0;
while(container.previousSibling){
// console.log(container.previousSibling.textContent.trim());
// console.log(container.previousSibling.textContent.trim().length);
str += container.previousSibling.textContent.trim();
offset += container.previousSibling.textContent.trim().length;
container = container.previousSibling;
i++;
// console.log(offset,container.previousSibling.textContent.trim().length)
}
selection是对当前激活选中区(即高亮文本)进行操作。
在非IE浏览器(Firefox、Safari、Chrome、Opera)下可以使用window.getSelection()获得selection对象,本文讲述的是标准的selection操作方法。文中绝大部分内容来自 https://developer.mozilla.org/en/DOM/Selection
术语
以下几个名词是英文文档中的几个名词。
- anchor
- 选中区域的“起点”。
- focus
- 选中区域的“结束点”。
- range
- 是一种fragment(HTML片断),它包含了节点或文本节点的一部分。一般情况下,同一时刻页面中只可能有一个range,也有可能是多个range(使用Ctrl健进行多选,不过有的浏览器不允许,例如Chrome)。可以从selection中获得range对象,也可以使用document.createRange()方法获得。
属性
- anchorNode
- 返回包含“起点”的节点。
- anchorOffset
- “起点”在anchorNode中的偏移量。
- focusNode
- 返回包含“结束点”的节点。
- focusOffset
- “结束点”在focusNode中的偏移量。
- isCollapsed
- “起点”和“结束点”是否重合。
- rangeCount
- 返回selection中包含的range对象的数目,一般存在一个range,Ctrl健配合使用可以有多个。
方法
- getRangeAt(index)
- 从当前selection对象中获得一个range对象。
index:参考rangeCount属性。
返回:根据下标index返回相应的range对象。 - collapse(parentNode, offset)
- 将开始点和结束点合并到指定节点(parentNode)的相应(offset)位置。
parentNode:焦点(插入符)将会在此节点内。
offset: 取值范围应当是[0, 1, 2, 3, parentNode.childNodes.length]。- 0:定位到第一个子节点前。
- 1:第二个子节点前。
- ……
- childNodes.length-1:最后一个子节点前。
- childNodes.length:最后一个子节点后。
Mozilla官方文档 中讲到取值为0和1,经测试不准确。文档中还有一句不是十分清楚“The document is not modified. If the content is focused and editable, the caret will blink there.”
- extend(parentNode, offset)
- 将“结束点”移动到指定节点(parentNode)的指定位置(offset)。
“起点”不会移动,新的selection是从“起点”到“结束点”的区域,与方向无关(新的“结束点”可以在原“起点”的前面)。
parentNode:焦点将会在此节点内。
Offset:1,parentNode的最后;0,parentNode的最前。 - modify(alter, direction, granularity)
- 改变焦点的位置,或扩展|缩小selection的大小
alter:改变的方式。”move”,用于移动焦点;”extend”,用于改变selection。
direction:移动的方向。可选值forward | backword或left | right
granularity:移动的单位或尺寸。可选值,character", "word", "sentence", "line", "paragraph", "lineboundary", "sentenceboundary", "paragraphboundary", or "documentboundary"。
Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1才会支持此函数, 官方文档:https://developer.mozilla.org/en/DOM/Selection/modify - collapseToStart()
- 将“结束点”移动到,selction的“起点”,多个range时也是如此。
- collapseToEnd()
- 将“起点”移动到,selction的“结束点”,多个range时也是如此。
- selectAllChildren(parentNode)
- 将parentNode的所有后代节点(parentNode除外)变为selection,页面中原来的selection将被抛弃。
- addRange(range)
- 将range添加到selection当中,所以一个selection中可以有多个range。
注意Chrome不允许同时存在多个range,它的处理方式和Firefox有些不同。 - removeRange(range)
- 从当前selection移除range对象,返回值undefined。
Chrome目前没有改函数,即便是在Firefox中如果用自己创建(document.createRange())的range作为参数也会报错。
如果用oSelction.getRangeAt()取到的,则不会报错。 - removeAllRanges()
- 移除selection中所有的range对象,执行后anchorNode、focusNode被设置为null,不存在任何被选中的内容。
- toString()
- 返回selection的纯文本,不包含标签。
- containsNode(aNode, aPartlyContained)
- 判断一个节点是否是selction的一部分。
aNode:要验证的节点。
aPartlyContained:true,只要aNode有一部分属于selection就返回true;false,aNode必须全部属于selection时才返回true。
区域可编辑contenteditable的问题总结的更多相关文章
- Emacs和Ultra Edit列编辑模式
在emacs中可以使用C-r系列组合键进行区域选择编辑,或者使用emacs自带的cua-mode,然后键入C-ret进行可视化列编辑. 使用Ultra Edit同样可以方便的进入列编辑模式,只需要按下 ...
- HTML5-contentEditable属性规定是否可编辑元素的内容
contentEditable='true' :可以编辑 contentEditable='false' :不可以编辑
- ZBrush软件如何编辑物体
新手在刚接触ZBrush®的时候,想要选中模型进行编辑,有时怎么都选不中,当再次画的时候只能在边上新建一个,还是不能进行编辑,遇到类似问题,你是如何解决的,本文将为您讲解ZBrush中怎么选中物体并进 ...
- 如何使用ABBYY FineReader 手动管理文档区域
在运用OCR编辑器时,ABBYY FineReader 15(Windows系统)OCR文字识别软件会对扫描仪或数码相机导入的图像进行识别和检测.在识别和检测之前,软件会自动对PDF文档中的文本.图片 ...
- Javascript高级编程学习笔记(81)—— 富文本(1)
富文本编辑 富文本编辑又称为: WYSIWYG(What You See Is What You Get,所见即所得) 常用于博客等用途,虽然没有规范,但是在IE最先引入后其他的浏览器厂商也相继完成了 ...
- Angular 富文本编辑之路的探索
作者:杨振兴Worktile 前端工程师,PingCode Wiki 产品技术负责人 PingCode Wiki 提供结构化知识库来记载信息和知识,便于团队沉淀经验.共享资源,欢迎大家注册试用 本文主 ...
- 【odoo14】第十四章、CMS网站开发
第十四章.CMS网站开发** Odoo有一个功能齐全的内容管理系统(CMS).通过拖放功能,你的最终用户可以在几分钟内设计一个页面,但是在Odoo CMS中开发一个新功能或构建块就不是那么简单了.在本 ...
- 吐槽贴:百度地图 api 封装 的实用功能 [源码下载]
ZMap 类 功能介绍 ZMap 是学习百度地图 api 接口,开发基本功能后整的一个脚本类,本类方法功能大多使用 prototype 原型 实现: 包含的功能有:轨迹回放,圈画区域可编辑,判断几个坐 ...
- Linux笔记:使用Vim编辑器
Vi编辑器是Unix系统上早先的编辑器,在GNU项目将Vi编辑器移植到开源世界时,他们决定对其作一些改进. 于它不再是以前Unix中的那个原始的Vi编辑器了,开发人员也就将它重命名为Vi improv ...
随机推荐
- P3596 [POI2015]MOD
$ \color{#0066ff}{ 题目描述 }$ 给定一棵无根树,边权都是1,请去掉一条边并加上一条新边,定义直径为最远的两个点的距离,请输出所有可能的新树的直径的最小值和最大值 \(\color ...
- O(n^2) 级别的排序算法
o(n^2) 的排序算法.性能那么差,为什么还要学习? 首先,它是基础,千里之行,始于足下.它编码简单,容易实现,是一些简单情景的首选,它能给我们的问题一个暴力的解法,这样的解法也许不是最优的,但是它 ...
- [jvm] JVM体系结构
一.jvm 运行时数据区域 程序计数器 java虚拟机栈 本地方法栈 java堆 方法区 运行时常量池 直接内存(非JVM区域) 二.深入探讨HotSpot虚拟机在Java堆中对象分配.布局和访问的全 ...
- HTML中title前面小图标的实现
做一个比较正规的网站,需要在标题栏前面加上相应的小图标,会好看的多.效果大致如下: 其实实现起来很简单,只要在html文件中的<head></head>标签中加上: <l ...
- AttributeError: module 'yagmail' has no attribute 'SMTP',关于使用yagmail发邮件报错的解决方法
想用yagmail,发送自动化测试结果邮件,发现运行的时候报错.最后发现是自己的脚本名称用的yagmail.py,更改成另一个就好,换了my_yagmail.py 再运行OK啦!!!!
- Django--队列2
celery 4.2 -Ofair现在是默认的调度策略 关于-Ofair命令行选项的作用存在很多混淆,并且在解释中使用术语“预取”可能没有帮助,因为这个术语在AMQP中有多么混乱. 当使用prefor ...
- STM32基础分析——PWM配置
在使用STM32F103产生固定频率.固定占空比的PWM波时,虽然有官方以及众多开发板提供的例程,但是关于有点问题并没有说的很清晰,并且<STM32F10X参考手册>的中文翻译可能容易造成 ...
- P4320 道路相遇
[Luogu4320] 必经点数==圆方树上两点路径上圆点数 也就等于边数/2+1 没什么好说的 , 看代码 #include<cstdio> #include<iostream&g ...
- Kibana6.x.x源码分析--启动时无反应分析
今天执行启动命令后,不报错,但是也没有反应,一时不知道是什么原因造成的,后来经过分析发现,无意间删除了根目录下的一个文件夹plugins,重新创建上这个文件夹后,再次运行就OK了.
- 详解SimpleXML添加_修改_删除_遍历XML节点属性
SimpleXML概述 要处理XML 文件,有两种传统的处理思路:SAX 和DOM.SAX 基于事件触发机制,对XML 文件进行一次扫描,完成要进行的处理:DOM 则将整个XML 文件构造为一棵DOM ...