JS Range使用总结

在网上查找Range相关资料时,发现都是残缺不全的,最后在W3C官方查找到一篇最为全面的介绍Range的文章,现将文章总结如下,希望对大家有所帮助。

Range的定义

当用户浏览一些页面时,经常使用鼠标选中一些文本,而JS中的Range对象,就是用来标识用户选中了哪些文本。

用户选中的文本,都是有起始和结束的,同样,我们可以用起始结束两个边界点来生成一个Range对象,而边界点的定义是通过Node节点+偏移的形式。

举个例子,当我们的网页是如下代码时,网页就会自动选择如图所示内容:

<body>
  <h1>Title</h1>
  <p>Blah xyz.</p>
</body>
<script>
  //创建Range
  let range = document.createRange();
  //设置Range的起始和结束边界点
  let startNode = document.getElementsByTagName('h1')[0].childNodes[0];
  let endNode = document.getElementsByTagName('p')[0].childNodes[0];
  range.setStart(startNode, 2);
  range.setEnd(endNode, 1);
  //将Range设为选中状态
  document.getSelection().addRange(range);
</script>

获取用户选中的文本

用户选中文本时,获取用户选中的文本,在实际编码过程中也是经常用到的, 以下代码,当用户选择文字时,会在控制台打印相应的起始和结束边界点。

<body>
  <h1>Title</h1>
  <p>Blah xyz.</p>
</body>
<script>
  //获取用户选中内容的起始和结束边界点
  document.onselectionchange = function() {
    let {
      anchorNode,
      anchorOffset,
      focusNode,
      focusOffset
    } = document.getSelection();
    //打印,只是做个演示
    console.log(anchorNode, anchorOffset)
    console.log(focusNode, focusOffset)
  };
</script>

Range常用API

下面列出Range常用的API

创建Range

DocumenrRange包含createRange()函数,可用于创建Range对象。

interface DocumentRange {
    Range createRange();
}

修改Range的范围

通过修改边界点来修改Range的范围。

void setStart(in Node parent, in long offset)
                    raises(RangeException);
void setEnd(in Node parent, in long offset)
                    raises(RangeException);

对比边界点

我们可以通过对比边界点来比较两个Range。

short compareBoundaryPoints(in CompareHow how, in Range sourceRange)
                    raises(RangeException);

删除Range

void deleteContents();
(1) <FOO>A**B<MOO>CD</MOO>**CD</FOO> --><FOO>A^CD</FOO>
(2) <FOO>A<MOO>B**C</MOO>D**E</FOO> --><FOO>A<MOO>B</MOO>^E</FOO>
(3) <FOO>X**Y<BAR>Z**W</BAR>Q</FOO> --><FOO>X^<BAR>W</BAR>Q</FOO>
(4) <FOO><BAR1>A**B</BAR1><BAR2/><BAR3>C**D</BAR3></FOO>--><FOO><BAR1>A</BAR1>^<BAR3>D</BAR3>

以上是不同情况下,删除Range后,剩下的内容。(其中**内部包含的是否选中的内容)

内容克隆

可以使用如下方法克隆Range中的内容。(注意返回类型)

DocumentFragment cloneContents();

插入内容

可以使用如下方法在Range中插入一个节点。节点将被插入Range的起始边界点处。

void insertNode(in Node n) raises(RangeException);

包裹内容

可以使用如下方法包裹内容。(包裹:使用指定的节点包围Range)

void surroundContents(in Node newParent);

example:

<BAR>A**B<MOO>C</MOO>D**E</BAR>
使用函数 surroundContents(FOO)后:
<BAR>A**<FOO>B<MOO>C</MOO>D</FOO>**E</BAR>

FOO为元素节点。

Range其他接口

// Introduced in DOM Level 2:
interface Range {
    readonly attribute Node startContainer;
    // raises(DOMException) on retrieval

    readonly attribute long startOffset;
    // raises(DOMException) on retrieval

    readonly attribute Node endContainer;
    // raises(DOMException) on retrieval

    readonly attribute long endOffset;
    // raises(DOMException) on retrieval

    readonly attribute boolean collapsed;
    // raises(DOMException) on retrieval

    readonly attribute Node commonAncestorContainer;
    // raises(DOMException) on retrieval

    void setStart( in Node refNode, in long offset)
    raises(RangeException,
        DOMException);
    void setEnd( in Node refNode, in long offset)
    raises(RangeException,
        DOMException);
    void setStartBefore( in Node refNode)
    raises(RangeException,
        DOMException);
    void setStartAfter( in Node refNode)
    raises(RangeException,
        DOMException);
    void setEndBefore( in Node refNode)
    raises(RangeException,
        DOMException);
    void setEndAfter( in Node refNode)
    raises(RangeException,
        DOMException);
    void collapse( in boolean toStart)
    raises(DOMException);
    void selectNode( in Node refNode)
    raises(RangeException,
        DOMException);
    void selectNodeContents( in Node refNode)
    raises(RangeException,
        DOMException);

    // CompareHow
    const unsigned short START_TO_START = 0;
    const unsigned short START_TO_END = 1;
    const unsigned short END_TO_END = 2;
    const unsigned short END_TO_START = 3;

    short compareBoundaryPoints( in unsigned short how, in Range sourceRange)
    raises(DOMException);
    void deleteContents()
    raises(DOMException);
    DocumentFragment extractContents()
    raises(DOMException);
    DocumentFragment cloneContents()
    raises(DOMException);
    void insertNode( in Node newNode)
    raises(DOMException,
        RangeException);
    void surroundContents( in Node newParent)
    raises(DOMException,
        RangeException);
    Range cloneRange()
    raises(DOMException);
    DOMString toString()
    raises(DOMException);
    void detach()
    raises(DOMException);
};

接口中各个属性和函数的意义请参考官方网站

总结

Range在进行前端Web开发时很少用到,但是在实际开发时,往往会遇到一些问题很难在百度上找到资料,这时不妨到官方网站看看,相信一定会有所收获!

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇