一、如何在可编辑区域div的光标处通过点击事件来添加文本内容

下面的例子是可编辑div的区域添加文本内容和判断光标位置的方法

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. </head>
  7. <body>
  8. 焦点位置:<input id="i1">选中文本:<input id="i2">
  9.  
  10. <div id="d1" contenteditable="true" style="width:200px;height:100px;border:1px solid black">1234567890abcdef
  11. </div>
  12. <button id="add">添加文字</button>
  13. </body>
  14. <script type="text/javascript">
  15. add.onclick=function () {
  16. var obj= d1;
  17. var range, node;
  18. if(!obj.hasfocus) {
  19. obj.focus();
  20. }
  21. if (window.getSelection && window.getSelection().getRangeAt) {
  22. range = window.getSelection().getRangeAt(0);
  23. range.collapse(false);
  24. node = range.createContextualFragment('10000ss');
  25. var c = node.lastChild;
  26. range.insertNode(node);
  27. if(c){
  28. range.setEndAfter(c);
  29. range.setStartAfter(c)
  30. }
  31. var j = window.getSelection();
  32. j.removeAllRanges(); range = window.getSelection().getRangeAt(0);
  33. j.addRange(range);
  34.  
  35. } else if (document.selection && document.selection.createRange) {
  36. document.selection.createRange().pasteHTML(text);
  37. }
  38. }
  39. document.onselectionchange = function (e) {
  40. // ie11
  41. //判断是否支持document.selection属性
  42. if (document.selection) {
  43. var pos = 0;
  44. var range = document.selection.createRange();
  45. var srcele = range.parentElement();
  46. //新建一个range,焦点在开头
  47. var copy = document.body.createTextRange();
  48. copy.moveToElementText(srcele);
  49. //判断copy的焦点起始部分是否在range的焦点起始部分的后面
  50. for (pos = 0; copy.compareEndPoints("StartToStart", range) < 0; pos++) {
  51. //copy的焦点向后移动一个字符
  52. copy.moveStart("character", 1);
  53. }
  54. document.getElementById('i1').value = pos;
  55. document.getElementById('i2').value = range.htmlText;
  56. }
  57. // chrome uc
  58. if (window.getSelection) {
  59. //获取Selection对象
  60. var se = window.getSelection();
  61. //获取起始位置,这个是字符的序号位置,而不是坐标
  62. var start = se.anchorOffset;
  63. //获取结束位置
  64. var end = se.focusOffset;
  65. //获取起始的dom元素
  66. var startEl = se.anchorNode.parentElement;
  67. //获取结束的dom元素
  68. var endEl = se.focusNode.parentElement;
  69. //获取起始dom元素的文本内容
  70. var startText = startEl.innerText;
  71. var txt = '';
  72. if (startEl == endEl) {
  73. txt = startText.substring(start, end);
  74. }
  75.  
  76. document.getElementById('i1').value = start;
  77. document.getElementById('i2').value = txt;
  78. }
  79. }
  80.  
  81. </script>
  82. </html>

  range.startOffset;相对于上个元素

获取整个元素偏移量的方法(复制的情况需要自己来计算)

  1. var range = window.getSelection().getRangeAt(0);
  2. var offset = 0;
  3. var str = '';
  4. var container = range.endContainer;
  5. console.log(container)
  6. var i=0;
  7. while(container.previousSibling){
  8. // console.log(container.previousSibling.textContent.trim());
  9. // console.log(container.previousSibling.textContent.trim().length);
  10. str += container.previousSibling.textContent.trim();
  11. offset += container.previousSibling.textContent.trim().length;
  12. container = container.previousSibling;
  13. i++;
  14. // console.log(offset,container.previousSibling.textContent.trim().length)
  15. }

  

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的问题总结的更多相关文章

  1. Emacs和Ultra Edit列编辑模式

    在emacs中可以使用C-r系列组合键进行区域选择编辑,或者使用emacs自带的cua-mode,然后键入C-ret进行可视化列编辑. 使用Ultra Edit同样可以方便的进入列编辑模式,只需要按下 ...

  2. HTML5-contentEditable属性规定是否可编辑元素的内容

    contentEditable='true' :可以编辑 contentEditable='false' :不可以编辑

  3. ZBrush软件如何编辑物体

    新手在刚接触ZBrush®的时候,想要选中模型进行编辑,有时怎么都选不中,当再次画的时候只能在边上新建一个,还是不能进行编辑,遇到类似问题,你是如何解决的,本文将为您讲解ZBrush中怎么选中物体并进 ...

  4. 如何使用ABBYY FineReader 手动管理文档区域

    在运用OCR编辑器时,ABBYY FineReader 15(Windows系统)OCR文字识别软件会对扫描仪或数码相机导入的图像进行识别和检测.在识别和检测之前,软件会自动对PDF文档中的文本.图片 ...

  5. Javascript高级编程学习笔记(81)—— 富文本(1)

    富文本编辑 富文本编辑又称为: WYSIWYG(What You See Is What You Get,所见即所得) 常用于博客等用途,虽然没有规范,但是在IE最先引入后其他的浏览器厂商也相继完成了 ...

  6. Angular 富文本编辑之路的探索

    作者:杨振兴Worktile 前端工程师,PingCode Wiki 产品技术负责人 PingCode Wiki 提供结构化知识库来记载信息和知识,便于团队沉淀经验.共享资源,欢迎大家注册试用 本文主 ...

  7. 【odoo14】第十四章、CMS网站开发

    第十四章.CMS网站开发** Odoo有一个功能齐全的内容管理系统(CMS).通过拖放功能,你的最终用户可以在几分钟内设计一个页面,但是在Odoo CMS中开发一个新功能或构建块就不是那么简单了.在本 ...

  8. 吐槽贴:百度地图 api 封装 的实用功能 [源码下载]

    ZMap 类 功能介绍 ZMap 是学习百度地图 api 接口,开发基本功能后整的一个脚本类,本类方法功能大多使用 prototype 原型 实现: 包含的功能有:轨迹回放,圈画区域可编辑,判断几个坐 ...

  9. Linux笔记:使用Vim编辑器

    Vi编辑器是Unix系统上早先的编辑器,在GNU项目将Vi编辑器移植到开源世界时,他们决定对其作一些改进. 于它不再是以前Unix中的那个原始的Vi编辑器了,开发人员也就将它重命名为Vi improv ...

随机推荐

  1. 使用vue-cli脚手架搭建项目,保存编译时出现的代码检查错误(ESLint)

    一.问题 出现这么写错误是什么原因呢?相信很多小白都会像我一样,第一次接触时有点二丈和尚摸不着头脑.其实是在你用vue-cli脚手架构建项目时用了ESLint代码检查工具,如下图 那么什么是ESLin ...

  2. 2、Numpy常用函数

    创建单位矩阵和读写文件使用eye()创建单位矩阵 # -*- coding: utf-8 -*- import numpy as np i = np.eye(3) print(i) 结果: [[ 1. ...

  3. redis中使用lua脚本

    lua脚本 Lua是一个高效的轻量级脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能 使用脚本的好处 1.减少网络开销,在Lua脚 ...

  4. Android 简单适配器(SimpleAdapter)

    1.介绍 2.简单适配器的实现方法 3.XML文件 (1)主页面布局 <?xml version="1.0" encoding="utf-8"?> ...

  5. 关于:“无法序列化会话状态。在“StateServer”或“SQLServer”模式下,...的问题

    关于:“无法序列化会话状态.在“StateServer”或“SQLServer”模式下,...的问题 错误描述: 无法序列化会话状态.在“StateServer”或“SQLServer”模式下,ASP ...

  6. Codeforces - 570D 离散DFS序 特殊的子树统计 (暴力出奇迹)

    题意:给定一棵树,树上每个节点有对应的字符,多次询问在\(u\)子树的深度为\(d\)的所有节点上的字符任意组合能否凑成一个回文串 把dfs序存储在一个二维线性表中,一个维度记录字符另一个维度记录深度 ...

  7. [水题AC乐] - 贪心

    HDU - 1009 https://paste.ubuntu.com/p/rgSYpSKkwW/ POJ - 1017 麻烦的模拟 贪心 题意就是用尽量少的66h箱子装nnh的物品,贪心策略很明显, ...

  8. 1076 Wifi密码 (15 分)

    下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1:B-2:C-3:D-4:请同学们自己作答,每两日一 ...

  9. 剑指offer——面试题7:重建二叉树

    // 面试题7:重建二叉树 // 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输 // 入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1, // 2, ...

  10. PIXI 精灵及文本加载(4)

    预习下官网的知识. 及字母消除接上文 Pixi 精灵 Pixi拥有一个精灵类来创建游戏精灵.有三种主要的方法来创建它: 用一个单图像文件创建. 用一个 雪碧图 来创建.雪碧图是一个放入了你游戏所需的所 ...