上一篇,介绍了 range 对象的一些属性和方法,了解了一些基本操作,现在来介绍另外一个重要的对象:selection 对象;
MDN 的解释是:Selection 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。文本选区由用户拖拽鼠标经过文字而产生;
先来写一个基本的 HTML 结构:
1 <div id="box" class="box" contenteditable="true">abcd<span>efghispan>jk<p>mnopp><span>qrstwvuspan>xyzdiv>
选中:
看下 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是否为当前选区的一部分;