乐趣区

关于javascript:JavaScript中对光标和选区的操作

在一些业务场景,比方高亮文本、输出编辑、等场景中须要对光标和选区进行操作时,能够应用浏览器提供的 Selection 对象和 Range 对象来操作光标和选区。

Selection 对象

Selection 对象示意用户抉择的选区或插入符号的以后地位,它可能横跨多个元素。

// 获取 Selection 对象
window.getSelection();

用户可能从左到右(与文档方向雷同)抉择文本或从右到左(与文档方向相同)抉择文本。

anchor(锚点): 指向用户开始抉择的中央。
focus(焦点): 指向用户完结抉择的中央。

如果你应用鼠标抉择文本的话,anchor 就指你按下鼠标键的中央,而 focus 就指你松开鼠标键的中央。anchorfocus 的概念不能与选区的起始地位和终止地位混同,因为 anchor 可能在 focus 的后面,也可能在 focus 的前面,这取决于你抉择文本时鼠标挪动的方向,也就是按下鼠标键和松开鼠标键的地位。

如下图所示:

属性:

  • anchorNode: 锚点(anchor)所在节点。
  • anchorOffset:

    • 如果 anchorNode 是文本节点、正文节点,返回锚点(anchor)到该节点中第一个字的字符个数。
    • 如果 anchorNode 是元素节点,返回锚点(anchor)之前的同级节点总数。
  • focusNode: 焦点(focus)所在节点。
  • focusOffset:

    • 如果 focusNode 是文本节点、正文节点,返回焦点(focus)到该节点中的第一个字的字符个数。
    • 如果 focusNode 是元素节点,返回焦点(focus)之前的同级节点总数。
  • isCollapsed: 示意选区的起始地位和终止地位是否重合的 Boolean 值,如果为 true,能够认为以后没有内容选中。
  • rangeCount: 选区中蕴含的 Range 对象数量。
  • type: 形容以后选区的类型,有以下三个值:

    • None: 以后没有抉择。
    • Caret: 仅单击,但未抉择,选区已折叠(即光标在字符之间,并未处于选中状态)。
    • Range: 抉择的是一个范畴。

留神:
以上所有属性都是 只读属性

办法:

  • addRange(range)

    向选区(Selection 对象)中增加一个区域(Range 对象)。

    参数:

    range:一个区域对象

    示例:

    <p id="text"> 文本 </p>
    // 增加一个选区
    var text = document.querySelector("#text");
    var selObj = window.getSelection();
    var rangeObj = document.createRange();
    rangeObj.selectNode(text);
    selObj.addRange(rangeObj);
  • collapse(parentNode,offset)

    收起以后选区到一个点。文档不会产生扭转。

    参数:

    parentNode:光标落在的指标节点
    offset:可选,在指标节点内的偏移量

    示例:

    <div contenteditable="true" id="text"> 文本 </div>
    // 收起选区到一个点,光标落在一个可编辑元素上
    var text = document.querySelector("#text")
    window.getSelection().collapse(text,0);
  • collapseToEnd()

    勾销以后选区,并把光标定位在原选区的最开端处。

    参数:

    示例:

    var selObj = window.getSelection();
    selObj.collapseToEnd();
  • collapseToStart()

    勾销以后选区,并把光标定位在原选区的最开始处。

    参数:

    示例:

    var selObj = window.getSelection();
    selObj.collapseToStart();
  • containsNode(aNode,aPartlyContained)

    判断指定的节点是否蕴含在 Selection 对象中(即是否被选中)。

    参数:

    aNode:用于判断是否蕴含在 Selection 对象中的节点。
    aPartlyContained
    当此参数为 true 时,Selection 对象蕴含 aNode 的一部分或全副时,containsNode() 办法返回 true
    当此参数为 false(默认值)时,只有 Selection 对象齐全蕴含 aNode 时,containsNode() 办法才返回 true

    示例:

    <div id="text"> 文本 </div>
    var text = document.querySelector("#text");
    var selObj = window.getSelection();
    var contains = selObj.containsNode(text);
  • deleteFromDocument()

    DOM 中删除选中的文档片段。

    参数:

    示例:

    var selObj = window.getSelection();
    selObj.deleteFromDocument();
  • extend(node,offset)

    挪动选区的焦点(focus)到指定的点。选区的锚点(anchor)不会挪动。选区将从锚点(anchor)开始到新的焦点(focus),不论方向。

    参数:

    node:焦点(focus)会被移至此节点内。
    offset:可选,默认值为 0,焦点(focus)会被移至 node 内的偏移地位。

    示例:

    <div id="text"> 文本 </div>
    var text = document.querySelector("#text");
    var selObj = window.getSelection();
    selObj.extend(text);
  • getRangeAt(index)

    返回一个以后选区蕴含的 Range 对象。

    参数:

    index:该参数指定 Range 对象的索引。如果该数值大于或等于 rangeCount,将会报错。

    示例:

    // 获取一个 Selection 对象
    var selObj = window.getSelection();
    // 获取一个 Range 对象
    var rangeObj  = selObj.getRangeAt(0);
  • modify(alter,direction,granularity)

    通过文本命令来更改以后选区或光标地位。

    参数:

    alter:扭转类型,传入 move 来挪动光标地位,或者 extend 来扩大以后选区。
    direction:调整选区的方向。你能够传入 forwardbackward 来依据选区内容的语言书写方向来调整。或者应用 leftright 来指明一个明确的调整方向。
    granularity:调整的间隔颗粒度。可选值有 characterwordsentencelineparagraphlineboundarysentenceboundaryparagraphboundarydocumentboundary

    示例:

    var selection = window.getSelection();
    selection.modify("extend", "forward", "word");
  • removeAllRanges()

    会从以后 Selection 对象中移除所有的 Range 对象,勾销所有的抉择。

    参数:

    示例:

    var selObj = window.getSelection();
    selObj.removeAllRanges();
  • removeRange(range)

    将一个 Range 对象从选区中移除。

    参数:

    range:一个将从选区中移除的 Range 对象

    示例:

    var selObj = window.getSelection();
    var rangeObj = selObj.getRangeAt(0)
    selObj.removeRange(rangeObj);
  • selectAllChildren(parentNode)

    把指定元素的所有子元素设置为选区(该元素自身除外),并勾销之前的选区。

    参数:

    parentNode:指定元素

    示例:

    <div id="selectAll">
      <div> 文本 1 </div>
      <div> 文本 2 </div>
    </div>
    var selectAll = document.querySelector("#selectAll");
    var selObj = window.getSelection();
    selObj.selectAllChildren(selectAll);
  • setBaseAndExtent(anchorNode,anchorOffset,focusNode,focusOffset)

    选中两个特定 DOM 节点之间的内容。

    参数:

    anchorNode:选中内容的开始节点
    anchorOffset:选区起始地位在 anchorNode 内的偏移量。
    如果 anchorNode 是文本节点,示意选区起始地位在该节点第几个字符地位。
    如果 anchorNode 是元素节点,示意选区起始地位在该节点内第几个子节点的地位。
    focusNode:选中内容的完结节点
    focusOffset:选区终止地位在 focusNode 内的偏移量。
    如果 focusNode 是文本节点,示意选区终止地位在该节点第几个字符地位。
    如果 focusNode 是元素节点,示意选区终止地位在该节点内第几个子节点的地位。

示例:

<div id="start"></div>
<div id="end"></div>
var start = document.querySelector("#start");
var end = document.querySelector("#end");
var selObj = window.getSelection();
selObj.setBaseAndExtent(start,0,end,0);
  • toString()

    返回代表以后 Selection 对象的字符串,例如以后抉择的文本。

    参数:

    示例:

    var selObj = window.getSelection();
    selObj.toString();

Range 对象

Range 对象示意被选中的文档片段。一个 Range 对象可能蕴含整个元素节点,也可能蕴含元素节点的一部分,例如文本节点的一部分文字。用户通常只能抉择一个 Range 对象,然而有的时候用户也有可能抉择多个 Range 对象(只有火狐浏览器能够抉择多个 Range 对象)。

能够用 Document 对象的 Document.createRange 办法创立 Range,也能够用 Selection 对象的 getRangeAt 办法获取 Range。另外,还能够通过 Document 对象的构造函数 Range() 来失去 Range

属性:

  • collapsed: 返回一个示意起始地位和终止地位是否雷同的 Boolean 值。
  • commonAncestorContainer: 返回蕴含 startContainerendContainer 的最深一级的节点。
  • endContainer: 返回蕴含 Range 起点地位的节点。
  • endOffset:

    • 如果 endContainer 是文本节点、正文节点,返回该节点第一个字到选区边界的字符个数(即被选中的字符个数)。
    • 如果 endContainer 是元素节点,返回选区终止地位之后第一个节点之前的同级节点总数。
  • startContainer: 返回蕴含 Range 开始地位的节点。
  • startOffset:

    • 如果 startContainer 是文本节点、正文节点,返回该节点第一个字到选区边界的字符个数(即未被选中的字符个数)。
    • 如果 startContainer 是元素节点,返回选区起始地位第一个节点之前的同级节点总数。

留神:
以上所有属性都是 只读属性

办法:

  • cloneContents()

    返回一个文档片段,它是 Range 对象中所有节点的正本。

    参数:

    示例:

    // 在文档中插入选中元素
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    documentFragment = rangeObj.cloneContents();
    document.body.appendChild(documentFragment);
  • cloneRange()

    返回一个 Range 对象的正本(两个对象各自做出扭转,都不会影响另一方)。

    参数:

    示例:

    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    clone = rangeObj.cloneRange(); 
  • collapse(toStart)

    向开始或完结方向折叠 Range

    参数:

    toStart:可选,Boolean值(默认值 false),true 折叠到 Range 的开始方向,false 折叠到完结方向。

    示例:

    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    rangeObj.collapse(true);
  • compareBoundaryPoints(how, sourceRange)

    比拟两个 Range 对象的起始地位节点或完结地位节点。

    参数:

    how 示意比拟办法的常量:

      Range.END_TO_END:比拟 sourceRange 对象的完结地位节点和原 Range 对象的完结地位节点。Range.END_TO_START:比拟 sourceRange 对象的完结地位节点和原 Range 对象的起始地位节点。Range.START_TO_END:比拟 sourceRange 对象的起始地位节点和原 Range 对象的完结地位节点。Range.START_TO_START:比拟 sourceRange 对象的起始地位节点和原 Range 对象的起始地位节点。

    sourceRange:一个与原 Range 对象比拟的 Range 对象。

    返回值

    compare 示意一个数字:

      -1:原 Range 对象的比拟节点在 sourceRange 对象的比拟节点之前  
      0:原 Range 对象的比拟节点在 sourceRange 对象的比拟节点的雷同地位   
      1:原 Range 对象的比拟节点在 sourceRange 对象的比拟节点之后  

    示例:

    <div id="range">range</div>
    <div id="sourceRange">sourceRange</div>
    var range, sourceRange, compare;
    range = document.createRange();
    range.selectNode(document.querySelector("#rang"));
    sourceRange = document.createRange();
    sourceRange.selectNode(document.querySelector("#sourceRange"));
    compare = range.compareBoundaryPoints(Range.START_TO_END, sourceRange);
  • comparePoint(referenceNode,offset)

    判断指定节点是在 Range 对象的之前、雷同还是之后地位。

    参数:

    referenceNode:与 Range 对象进行比拟的节点。
    offset:在 referenceNode 内的偏移量。
    如果 referenceNode 是文本节点、正文节点,offset 示意在该节点中字符的偏移地位。
    如果 referenceNode 是元素节点,offset 示意在该节点中子元素的偏移地位。

    示例:

    <div id="range">range</div>
    <div id="referenceNode">referenceNode</div>
    range = document.createRange();
    range.selectNode(document.querySelector("#range"));
    returnValue = range.comparePoint(document.querySelector("#referenceNode"), 0);
  • createContextualFragment(tagString)

    HTML 字符串转换为文档片段

    参数:

    tagString:要转换的 HTML 字符串。

    示例:

    <div id="range">range</div>
    var tagString = "<div>node</div>";
    var range = document.createRange();
    range.selectNode(document.querySelector("#range"));
    var documentFragment = range.createContextualFragment(tagString);
    document.body.appendChild(documentFragment);
  • deleteContents()

    DOM 中删除选中的文档片段,不返回删除的文档片段。

    参数:

    示例:

    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    rangeObj.deleteContents();
  • extractContents()

    DOM 中删除选中的文档片段,返回删除的文档片段(不保留 DOM 事件)。

    参数:

    示例:

    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    rangeObj.extractContents();
  • getBoundingClientRect()

    返回一个 DOMRect 对象,示意整个选区的地位信息。

    参数:

    示例:

    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    var boundingRect = rangeObj.getBoundingClientRect();
  • getClientRects()

    返回一个选区内所有元素调用 Element.getClientRects() 办法所得后果的列表。示意选区在屏幕上所占的区域。

    参数:

    示例:

    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    var boundingRect = rangeObj.getClientRects();
  • insertNode(newNode)

    在选区开始处插入一个节点。

    参数:

    newNode:须要插入的节点

    示例:

    <div id="insertNode">insertNode</div>
    <div id="node">node</div>
    range = document.createRange();
    newNode = document.querySelector("#node");
    range.selectNode(document.querySelector("#insertNode"));
    range.insertNode(newNode);
  • intersectsNode(referenceNode)

    返回一个 Boolean 值,判断指定节点和 Range 对象是否相交。

    参数:

    referenceNode:须要比拟的节点

    示例:

    <div id="referenceNode">referenceNode</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    referenceNode = document.querySelector("#referenceNode");
    rangeObj.intersectsNode(referenceNode);
  • isPointInRange(referenceNode,offset)

    返回一个 Boolean 值,判断指定节点是否在 Range 对象内。

    参数:

    referenceNode:指定节点
    offset:在 referenceNode 内的偏移量。
    如果 referenceNode 是文本节点,offset 示意在该节点中字符的偏移地位。
    如果 referenceNode 是元素节点,offset 示意在该节点中子元素的偏移地位。

    示例:

    <div id="referenceNode">referenceNode</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    referenceNode = document.querySelector("#referenceNode");
    rangeObj.isPointInRange(referenceNode,0);
  • selectNode(referenceNode)

    将指定节点蕴含在 Range 对象内。

    参数:

    referenceNode:指定节点

    示例:

    <div id="referenceNode">referenceNode</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    referenceNode = document.querySelector("#referenceNode");
    rangeObj.selectNode(referenceNode);
  • selectNodeContents(referenceNode)

    将指定节点的内容蕴含在 Range 对象内。

    参数:

    referenceNode:指定节点

    示例:

    <div id="referenceNode">referenceNode</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    referenceNode = document.querySelector("#referenceNode");
    rangeObj.selectNodeContents(referenceNode);
  • setEnd(endNode,endOffset)

    设置选区的终止地位。

    参数:

    endNode:终止地位所在的节点
    endOffset:在 endNode 内的偏移量。
    如果 endNode 是文本节点、正文节点,endOffset 示意在该节点中字符的偏移地位。
    如果 endNode 是元素节点,endOffset 示意在该节点中子元素的偏移地位。

    示例:

    <div id="endNode">endNode</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    var endNode = document.querySelector("#endNode");
    rangeObj.setEnd(endNode,0)
  • setEndAfter(referenceNode)

    设置选区的完结地位在指定节点之后。

    参数:

    referenceNode:指定节点

    示例:

    <div id="referenceNode">referenceNode</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    var referenceNode = document.querySelector("#referenceNode");
    rangeObj.setEndAfter(referenceNode)
  • setEndBefore(referenceNode)

    设置选区的完结地位在指定节点之前。

    参数:

    referenceNode:指定节点

    示例:

    <div id="referenceNode">referenceNode</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    var referenceNode = document.querySelector("#referenceNode");
    rangeObj.setEndBefore(referenceNode)
  • setStart(startNode,startOffset)

    设置选区的起始地位。

    参数:

    startNode:起始地位所在的节点
    startOffset:在 startNode 内的偏移量。
    如果 startNode 是文本节点、正文节点,startOffset 示意在该节点中字符的偏移地位。
    如果 startNode 是元素节点,startOffset 示意在该节点中子元素的偏移地位。

    示例:

    <div id="startNode">startNode</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    startNode = document.querySelector("#startNode");
    rangeObj.setStart(startNode,0)
  • setStartAfter(referenceNode)

    设置选区的起始地位在指定节点之后。

    参数:

    referenceNode:指定节点

    示例:

    <div id="referenceNode">referenceNode</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    referenceNode = document.querySelector("#referenceNode");
    rangeObj.setStartAfter(referenceNode)
  • setStartBefore(referenceNode)

    设置选区的起始地位在指定节点之前。

    参数:

    referenceNode:指定节点

    示例:

    <div id="referenceNode">referenceNode</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    referenceNode = document.querySelector("#referenceNode");
    rangeObj.setStartBefore(referenceNode)
  • surroundContents(newParent)

    把指定节点插入选区的起始地位,而后把指定节点的内容替换为选区的内容。

    参数:

    newParent:指定节点

    示例:

    <div id="newParent">newParent</div>
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    newParent = document.querySelector("#newParent");
    rangeObj.surroundContents(newParent)
  • toString()

    返回代表以后 Range 对象的字符串,例如以后抉择的文本。

    参数:

    示例:

    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    var rangeStr = rangeObj.toString();

选区中的多个区域

一个 Selection 对象示意用户抉择的区域(Range 对象)的汇合,通常它只蕴含一个区域,拜访形式如下:

// 获取一个 Selection 对象
var selObj = window.getSelection();
// 获取一个 Range 对象
var rangeObj  = selObj.getRangeAt(0);

只有火狐浏览器实现了多个区域,如下图所示:

批改选区款式

应用 ::selection 选择器能够匹配被选中的局部。
目前只有一小部分 CSS 属性能够用于 ::selection 选择器:

  • color
  • background-color
  • text-shadow

示例

示例地址

参考

Selection

Range

笔记 Javascript 的 Selection 对象:根本属性

利用 javascript 实现富文本编辑器

What is anchorNode , baseNode , extentNode and focusNode in the object returned by document.getSelection?

Coordinates of selected text in browser page

退出移动版