欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

编辑器开发之 Selection 对象的学习

程序员文章站 2022-05-14 13:19:24
上一篇,介绍了 range 对象的一些属性和方法,了解了一些基本操作,现在来介绍另外一个重要的对象:selection 对象; MDN 的解释是:Selection 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。文本选区由用户拖拽鼠标经过文字而产生; 先来 ......

上一篇,介绍了 range 对象的一些属性和方法,了解了一些基本操作,现在来介绍另外一个重要的对象:selection 对象;

mdn 的解释是:selection 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。文本选区由用户拖拽鼠标经过文字而产生;

先来写一个基本的 html 结构:

  1 <div id="box" class="box" contenteditable="true">abcd<span>efghi</span>jk<p>mnop</p><span>qrstwvu</span>xyz</div>

选中:

看下 selection 对象的信息:

  1 function getsel() {
  2   var sel = window.getselection();
  3   // 如果有 range
  4   if (sel.rangecount > 0) {
  5     var range = sel.getrangeat(0);
  6     console.log(range.clonecontents());
  7   }
  8   console.log(sel);
  9 }
 10 

这里主要关注的有这几个属性:

anchornode:返回选区的开始位置所在的节点,这里是最外面的 div;

anchoroffset:返回选区开始位置在开始节点中的位置;

focusnode:返回选区的结束位置所在的节点,这里是 span 标签;

focusoffset:返回选区的结束位置在结束节点中的位置;

iscollapsed:返回选区的开始位置和结束位置是否相同,检测选区是否折叠;

rangecount:返回 range 对象的数量;

注意:这个 rangecount 总是存在的,无论页面有没有可变的区域,只要鼠标点击了任何位置,它都会变成 1;

basenode,baseoffset属性和 ahchornode,anchoroffset相同;

extentnode,extentoffset属性和 focusnode,focusoffset相同;

 

selection 对象的一些重要方法:

getrangeat(index):根据索引返回 range 对象,需要注意的一点是:其他浏览器都是只有一个选区,但是在 firefox下,可以有多个选区,操作是按住 shift 多选;

collapse(parentnode, offset):折叠选区到某个位置,光标会在此处闪烁;

现在把光标移动到 p 标签的第三个字符前面:

  1 function setcollapse() {
  2     var sel = window.getselection();
  3     box.focus();
  4     var p = box.queryselector('p').firstchild;
  5     sel.collapse(p, 2); // 设置光标的位置在 p 标签的第三个字符前面
  6 
  7     if (sel.rangecount > 0) {
  8       var range = sel.getrangeat(0);
  9       console.log(range);
 10     }
 11   }

可以看到光标在字符 o 的前面闪烁;

collapsetostart:将光标设置到选区的起点,这个没什么好说的;

collapsetostart:将光标设置到选区的结束位置,这个也没啥好说的;

selectallchildren(node):将节点的所有子节点加入选区;

  1 function setselectallchildren() {
  2     var sel = window.getselection();
  3     sel.selectallchildren(box); // 把可编辑区的所有子节点纳入选区
  4 
  5     if (sel.rangecount > 0) {
  6       var range = sel.getrangeat(0);
  7       console.log(range.clonecontents());
  8     }
  9   }

可以看到所有的内容都放到选区内了;

addrange(range):将选区加入到 selection:

  1 function addrange() {
  2     var sel = window.getselection();
  3     sel.removeallranges();
  4     box.focus();
  5 
  6     // 将所有的子节点放到选区中
  7     var children = box.children;
  8     for(var i = 0; i < children.length; i++) {
  9       var range = document.createrange();
 10 
 11       console.log(children[i]);
 12       range.selectnode(children[i]);
 13       sel.addrange(range);
 14     }
 15 
 16     console.log(sel); // 打印 range 的数量
 17   }

这里是把所有的子节点放到选区中,但是好像只有 firefox 支持,其他的浏览器不支持多个 range;

removerange(range):删除指定的选区,只有 firefox 支持;

removeallranges:删除所有的选区;

deletefromdocument:从页面中删除选区中的内容;

selectionlanguagechange:当键盘的朝向发生改变后修改指针的bidi优先级;

tostring:返回当前选区的纯文本内容;

containsnode:判断某一个node是否为当前选区的一部分;