搜索
首页web前端js教程浅谈JavaScript中如何操作光标和选区?

JavaScript中如何操作光标和选区?下面本篇文章带大家了解一下 Selection 对象和 Range 对象,介绍一下怎么借助这两个对象来操作光标和选区。

浅谈JavaScript中如何操作光标和选区?

在一些业务场景,比如高亮文本、输入编辑、等场景中需要对光标和选区进行操作时,可以使用浏览器提供的 Selection 对象和 Range 对象来操作光标和选区。

Selection 对象

Selection 对象表示用户选择的选区或插入符号的当前位置,它可能横跨多个元素。

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

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

anchor (锚点): 指用户开始选择的地方。  
focus  (焦点): 指用户结束选择的地方。

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

如下图所示:

1.png

2.png

属性:

  • 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 字符串。

    示例:

    var tagString = "<div>node</div>";
    var range = document.createRange();
    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 表示在该节点中子元素的偏移位置。

    示例:

    3b7b3b86ce077e575e1f6b87cb37d1c4startNode94b3e26ee717c64999d7867364b1b4a3
    var selObj = window.getSelection();
    var rangeObj  = selObj.getRangeAt(0);
    startNode = document.querySelector("#startNode");
    rangeObj.setStart(startNode,0)
  • setStartAfter(referenceNode)

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

    参数:

    referenceNode:指定节点

    示例:

    <div id="startNode">startNode</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);

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

2.jpg

修改选区样式

使用 ::selection 选择器可以匹配被选中的部分。  
目前只有一小部分 CSS 属性可以用于 ::selection 选择器:

  • color
  • background-color
  • text-shadow

示例

2.gif

示例地址:https://www.kkkk1000.com/images/SelectionRange/selection.html

更多编程相关知识,请访问:编程视频!!

以上是浅谈JavaScript中如何操作光标和选区?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:segmentfault。如有侵权,请联系admin@php.cn删除
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),