区域可编辑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 ...
随机推荐
- 使用vue-cli脚手架搭建项目,保存编译时出现的代码检查错误(ESLint)
一.问题 出现这么写错误是什么原因呢?相信很多小白都会像我一样,第一次接触时有点二丈和尚摸不着头脑.其实是在你用vue-cli脚手架构建项目时用了ESLint代码检查工具,如下图 那么什么是ESLin ...
- 2、Numpy常用函数
创建单位矩阵和读写文件使用eye()创建单位矩阵 # -*- coding: utf-8 -*- import numpy as np i = np.eye(3) print(i) 结果: [[ 1. ...
- redis中使用lua脚本
lua脚本 Lua是一个高效的轻量级脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能 使用脚本的好处 1.减少网络开销,在Lua脚 ...
- Android 简单适配器(SimpleAdapter)
1.介绍 2.简单适配器的实现方法 3.XML文件 (1)主页面布局 <?xml version="1.0" encoding="utf-8"?> ...
- 关于:“无法序列化会话状态。在“StateServer”或“SQLServer”模式下,...的问题
关于:“无法序列化会话状态.在“StateServer”或“SQLServer”模式下,...的问题 错误描述: 无法序列化会话状态.在“StateServer”或“SQLServer”模式下,ASP ...
- Codeforces - 570D 离散DFS序 特殊的子树统计 (暴力出奇迹)
题意:给定一棵树,树上每个节点有对应的字符,多次询问在\(u\)子树的深度为\(d\)的所有节点上的字符任意组合能否凑成一个回文串 把dfs序存储在一个二维线性表中,一个维度记录字符另一个维度记录深度 ...
- [水题AC乐] - 贪心
HDU - 1009 https://paste.ubuntu.com/p/rgSYpSKkwW/ POJ - 1017 麻烦的模拟 贪心 题意就是用尽量少的66h箱子装nnh的物品,贪心策略很明显, ...
- 1076 Wifi密码 (15 分)
下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1:B-2:C-3:D-4:请同学们自己作答,每两日一 ...
- 剑指offer——面试题7:重建二叉树
// 面试题7:重建二叉树 // 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输 // 入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1, // 2, ...
- PIXI 精灵及文本加载(4)
预习下官网的知识. 及字母消除接上文 Pixi 精灵 Pixi拥有一个精灵类来创建游戏精灵.有三种主要的方法来创建它: 用一个单图像文件创建. 用一个 雪碧图 来创建.雪碧图是一个放入了你游戏所需的所 ...