美文网首页
Range与Selection对象(梁王的理论自习室)

Range与Selection对象(梁王的理论自习室)

作者: 梁王io | 来源:发表于2017-07-17 18:20 被阅读80次

    前言

    之前看quill源码(一个富文本编辑器)的时候第一次接触Range与Selection对象,之前也写过一篇文章总结了这两个对象,不过感觉略水,正好现在在重构一个atwho的功能,特写几篇总结下。、

    Selection

    Selection是什么

    selection是对当前激活选中区(即高亮文本)进行操作的对象。

    Selection有什么用

    我遇见的比较主要的就是获取选中区的Range

    Selection例子

    读者可以选中一些文字然后控制台输入下列代码

    userSelection = window.getSelection();
    userSelection.toString()
    

    Range

    Range是什么

    所谓"Range",是指HTML文档中任意一段内容。一个Range的起始点和结束点位置任意,甚至起始点和结束点可以是一样的(也就是空Range)。最常见的Range是用户文本选择范围(user text selection)。当用户选择了页面上的某一段文字后,你就可以把这个选择转为Range。当然,你也可以直接用程序定义Range。

    Range有什么用

    试想一下,在富文本编辑器里面,有一些情况是加粗或者倾斜选中的内容,Range指HTML文档中任意一段内容。

    在 HTML5 中,一个 Range 对象代表页面上的一段连续区域。通过 Range 对象,可以获取或修改页面上的任何区域。包含获取,修改,删除和替换等操作。

    Range的例子

    userSelection = window.getSelection();
    userSelection.getRangeAt(0).toString()
    

    Range与Selection

    每一个selection对象都有一个或者多个Range对象,每一个range对象代表用户鼠标所选取范围内的一段连续区域,在firefox中,可以通过ctrl键可以选取多个连续的区域,因此在firefox中一个selection对象有多个range对象,在其他浏览器中,用户只能选取一段连续的区域,因此只有一个range对象。
    所以你可以看到userSelection.getRangeAt(0)这个为什么会有个0
    getRangeAt方法有一个参数index,代表该Range对象的序列号;我们可以通过Selection对象的rangeCount参数的值判断用户是否选取了内容;

    属性与方法

    由于这种属性和方法的东西太多了,罗列出来没什么用,我就说一些我用过的部分属性和方法。

    Range对象的我用过的属性与方法(待补充)

    setStart, setEnd等

    setStart方法 用于将某个节点中的某处位置指定为Range对象所代表区域的起点位置,使用方法如下:

    rangeObj.setStart(node,curIndex);
    

    如上代码rangeObj代表一个Range对象,该setStart方法使用2个参数,第一个参数node代表一个节点,第二个参数是一个数字,当第一个参数node所代表的节点是一个内容为一段文字的文字节点时,该参数值用于指定将第几个文字的结束位置作为Range对象所代表的区域的起点位置;当第一个参数node所代表的节点中包括其他子节点时,该参数值用于将第几个子节点的结束位置指定为Range对象所代表的区域的起点位置;

    Selection对象的我用过的属性与方法(待补充)

    getRangeAt(index)
    从当前selection对象中获得一个range对象。
    index:参考rangeCount属性。
    返回:根据下标index返回相应的range对象。

    collapse(parentNode, offset)
    将开始点和结束点合并到指定节点(parentNode)的相应(offset)位置。

    实战

    需求是获取光标之前的内容,这个在我实现atwho(@)和添加标签(#)的时候使用过。

    代码

    // 这个函数获取用户选择部分的Range对象
    function getRange() {
      const selection = window.getSelection()
      if (selection && selection.rangeCount > 0) {
        return selection.getRangeAt(0)
      }
    }
    //这个获取光标前的Range
    function getPrecedingRange() {
      const r = getRange()
      if (r) {
        const range = r.cloneRange()
        range.collapse(true)
        // var el = closest(range.endContainer, d => d.contentEditable)
        // range.setStart(el, 0)
        range.setStart(range.endContainer, 0)
        return range
      }
    }
    // have fun
    getPrecedingRange().toString()
    

    相关文章

      网友评论

          本文标题:Range与Selection对象(梁王的理论自习室)

          本文链接:https://www.haomeiwen.com/subject/dutqkxtx.html