JavaScript之Range--或许会有点用

简介:

Range是JavaScript的内置对象,一般来讲用到的地方不是很多,主要是一些交互性比较强的场景可能会用到,比如高亮标注,用不到还好说,如果用到了查资料确实也是比较少的, 所以这里总结一下笔记,不会太深入。

需要注意的是这里很多方法都属于实验性功能, 所以生产环境使用的使用需要谨慎,具体可以参考MDN。这里不赘述了。

range的应用场景

这类相对比较生僻的api应用常见并不是很多, 这里我们先了解一下range的应用场景.

  1. 就是常见的高亮标注电子书之类的

  2. 人工标注机器学习所需的基础文档(我所做的)

当然应该也有很多其他场景, 我也没怎么接触. 有兴趣的可以自行了解

Range是什么

顾名思义,Range其实可以认为是一个选中的文字范围, 但是Range又不依赖于鼠标选中, 我们可以自行构造或者克隆。不过在细说Range之前我们先了解一下Selection。

如图当我们选中一段文字时, 我们就以通过window.getSelection来获取Selection对象


23cc3f3fa65b8c706c291b4ca113851fb276f053

56cea6b86559de54cdbde5cc2e6b8b679b97dd56

Selection可以window.getSelection().toString()直接获取选中的文字, 但是很多时候我们并不是要获取选中的文字,而是要得到选中文字所在位置并将其存储起来。这时候就是Range发挥作用的地方了。

window.getSelection().getRangeAt(0)可以将一个Selection对象转化为Range对象。

e4385f938d4c1a9034d3c02f4707fe2f1ed81f78

如上图,我们知道Dom元素排列是一段一段的, 这里的container就是指的每个段,offset就是选中的位置。Range肯定是连续的,这样我们就可以定位一段完整的Range。

Range的存储

如果作为高亮, Range必然是要存到服务器上的, 但是作为js对象, Range不可以直接存到数据库里,这时候就要对Range进行一定的处理了。

上面提到过Range是可以手动创建的:document.createRange



var range = document.createRange();

range.setStart(startNode, startOffset);
range.setEnd(endNode, endOffset);

这里startNode指startContainer, 自然就是指dom元素了,看到这里其实大家心里也该有点方案了,不好存储的无非就是dom元素了,那我们将dom元素转为选择器存起来就好了, 到时再通过选择器获取dom元素。

当然我们也有其他选择: xpath, 主要是我接手项目的时候就是利用的xpath, 将dom转为xpath的代码如下:


// 获取一个元素的xpath
function getElementXPath (element) {
  if (!element) return null

  if (element.id) {
    return `//*[@id=${element.id}]`
  } else if (element.tagName === 'BODY') {
    return '/html/body'
  } else {
    const sameTagSiblings = Array.from(element.parentNode.childNodes)
      .filter(e => e.nodeName === element.nodeName)
    const idx = sameTagSiblings.indexOf(element)

    return getElementXPath(element.parentNode) +
      '/' +
      element.tagName.toLowerCase() +
      (sameTagSiblings.length > 1 ? `[${idx + 1}]` : '')
  }
}

将xpath转化为Range:


function createRangeFromXPathRange (xpathRange) {
    var startContainer,
      endContainer,
      endOffset,
      evaluator = new XPathEvaluator()

    // must have legal start and end container nodes
    startContainer = evaluator.evaluate(
      xpathRange.startContainerPath,
      document.documentElement,
      null,
      XPathResult.FIRST_ORDERED_NODE_TYPE,
      null
    )
    if (!startContainer.singleNodeValue) {
      return null
    }

    if (xpathRange.collapsed || !xpathRange.endContainerPath) {
      endContainer = startContainer
      endOffset = xpathRange.startOffset
    } else {
      endContainer = evaluator.evaluate(
        xpathRange.endContainerPath,
        document.documentElement,
        null,
        XPathResult.FIRST_ORDERED_NODE_TYPE,
        null
      )
      if (!endContainer.singleNodeValue) {
        return null
      }

      endOffset = xpathRange.endOffset
    }

    // map to range object
    var range = document.createRange()
    range.setStart(startContainer.singleNodeValue, xpathRange.startOffset)
    range.setEnd(endContainer.singleNodeValue, endOffset)
    return range
  }




原文发布时间为:2018年06月02日
原文作者:_xiadd_

本文来源: 掘金 如需转载请联系原作者




相关文章
|
8月前
|
JavaScript 前端开发 测试技术
[小笔记]TypeScript/JavaScript模拟Python中的Range函数
[小笔记]TypeScript/JavaScript模拟Python中的Range函数
79 0
|
8月前
|
Web App开发 JavaScript 前端开发
JavaScript 中的 Range 和 Selection 对象
JavaScript 中的 `Range` 和 `Selection` 对象用于处理文本选择。`Range` 表示文档中选定的区域,而 `Selection` 表示用户选择的文本或光标位置。`Range` 可以创建并设置于任何元素或文本,具有多个属性(如 `startContainer`, `endContainer`, `collapsed`)和方法(如 `cloneContents`, `deleteContents`)。`Selection` 提供了获取和操作用户选择的方法,如 `anchorNode`, `focusNode` 和 `addRange`。两者在所有现代浏览器中基本兼容。
79 1
JavaScript 中的 Range 和 Selection 对象
|
2月前
|
JavaScript 前端开发
JavaScript中的原型 保姆级文章一文搞懂
本文详细解析了JavaScript中的原型概念,从构造函数、原型对象、`__proto__`属性、`constructor`属性到原型链,层层递进地解释了JavaScript如何通过原型实现继承机制。适合初学者深入理解JS面向对象编程的核心原理。
36 1
JavaScript中的原型 保姆级文章一文搞懂
|
6月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
118 2
|
2月前
JS+CSS3文章内容背景黑白切换源码
JS+CSS3文章内容背景黑白切换源码是一款基于JS+CSS3制作的简单网页文章文字内容背景颜色黑白切换效果。
23 0
|
6月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
164 4
|
6月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
93 4
|
6月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物交易平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物交易平台附带文章源码部署视频讲解等
85 4
|
6月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的大学生入伍人员管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的大学生入伍人员管理系统附带文章源码部署视频讲解等
101 4
|
6月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp宿舍管理系统的附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp宿舍管理系统的附带文章源码部署视频讲解等
96 3