0

0

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

青灯夜游

青灯夜游

发布时间:2021-06-30 10:46:06

|

4365人浏览过

|

来源于segmentfault

转载

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

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

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

Selection 对象

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

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

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

立即学习Java免费学习笔记(深入)”;

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: 一个区域对象

    示例:

    文本

    //添加一个选区
    var text = document.querySelector("#text");
    var selObj = window.getSelection();
    var rangeObj = document.createRange();
    rangeObj.selectNode(text);
    selObj.addRange(rangeObj);
  • collapse(parentNode,offset)

    收起当前选区到一个点。文档不会发生改变。

    参数:

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

    示例:

    文本
    //收起选区到一个点,光标落在一个可编辑元素上
    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

    示例:

    文本
    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 内的偏移位置。

    示例:

    文本
    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: 指定元素

    示例:

    文本1
    文本2
    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 是元素节点,表示选区终止位置在该节点内第几个子节点的位置。

示例:

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 对象的副本(两个对象各自做出改变,都不会影响另一方)。

    Vondy
    Vondy

    下一代AI应用平台,汇集了一流的工具/应用程序

    下载

    参数:

    示例:

    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 对象的比较节点之后

    示例:

    range
    sourceRange
    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 表示在该节点中子元素的偏移位置。

    示例:

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

    HTML 字符串转换为文档片段

    参数:

    tagString: 要转换的 HTML 字符串。

    示例:

    var tagString = "
    node
    "; 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:  需要插入的节点

    示例:

    insertNode
    node
    range = document.createRange();
    newNode = document.querySelector("#node");
    range.selectNode(document.querySelector("#insertNode"));
    range.insertNode(newNode);
  • intersectsNode(referenceNode)

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

    参数:

    referenceNode:需要比较的节点

    示例:

    referenceNode
    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 表示在该节点中子元素的偏移位置。

    示例:

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

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

    参数:

    referenceNode:指定节点

    示例:

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

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

    参数:

    referenceNode:指定节点

    示例:

    referenceNode
    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 表示在该节点中子元素的偏移位置。

    示例:

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

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

    参数:

    referenceNode:指定节点

    示例:

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

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

    参数:

    referenceNode:指定节点

    示例:

    referenceNode
    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 表示在该节点中子元素的偏移位置。

    示例:

    startNode

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

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

    参数:

    referenceNode:指定节点

    示例:

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

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

    参数:

    referenceNode:指定节点

    示例:

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

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

    参数:

    newParent:指定节点

    示例:

    newParent
    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

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

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

37

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

37

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.13

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

交互式图表和动态图表教程汇总
交互式图表和动态图表教程汇总

本专题整合了交互式图表和动态图表的相关内容,阅读专题下面的文章了解更多详细内容。

45

2026.01.13

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

9

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.2万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号