• Javascript高级编程学习笔记(54)—— DOM2和DOM3(6)范围选择


    范围

    为了让开发人员更加方便地控制页面“DOM2级遍历和范围”模块定义了“范围”接口

    通过该接口开发人员可以选择文档中的一个区域,而不必考虑元素的界限

    在常规操作不能有效地修改文档时,使用范围往往可以达到目的

    DOM中的范围

    DOM2级在Document类型中定义了 createRange()方法

    在兼容该接口的浏览器中,该方法属于document对象

    可以使用以下代码,检测浏览器对其的兼容

    var supportsRange = document.implementation.hasFeature("Range","2.0");
    var alsoSupportsRange = (typeof document.createRange ==="function");

    如果浏览器支持范围,那么就可以使用createRange()来创建范围

    var range = document.createRange();

    与节点类似,创建的范围也会和文档关联,不能用于其它文档

    每个范围由一个Range类型的实例表示

    下列属性提供了范围在文档中的位置信息

    • startContainer:包含范围起点的节点(即选区中第一个节点的父节点)
    • startOffset:范围起点在startContainer 中的偏移量
    • endContainer:包含范围终点的节点(即选区中最后一个节点的父节点)
    • endOffset:范围终点在endContainer中的偏移量
    • commonAncestorContainer:距离起点和终点最近的公共祖先节点

    用DOM范围实现简单选择

    使用范围来选择文档中的一部分,最简单的方式就是通过

    selectNode() 和 selectNodeContents()方法

    这两个方法都接收一个参数,即一个DOM节点

    selectNode 是将传入节点的整个节点作为范围

    selectNodeContents则是将传入节点的所有子节点作为范围

    例如:

    <p id = "p1"><b>hello</b>world!</p>

    对于以上HTML代码

    使用以下代码创建范围

    var range1 = document.createRange();
    var range2 = document.createRange();
    var p1 = document.getElementById('p1');
    
    range1 = range1.selectNode(p1);
    range2 = range2.selectNodeContents(p1);

    对于上述代码

    range1包含的文档内容如下:

    <p id = "p1"><b>hello</b>world!</p>

    range2包含的文档内容如下:

    <b>hello</b>world!

    此外,为了更加精细地控制将哪些节点包含在范围中,还可以使用以下方法

    • setStartBefore(refNode):将范围起点设置在 refNode 之前(也就是refNode作为范围的第一个子节点)
    • setStartAfter(refNode):将范围起点设置在 refNode 之后(即refNode的下一个同辈节点作为范围的第一个子节点)
    • setEndBefore(refNode):将范围终点设置在 refNode 之前
    • setEndAfter(refNode):将范围终点设置在 refNode 之后

    使用这里提到的方法会自动设置范围属性,当然也可以通过设置范围属性来改变选区的范围

    即startContainer、startOffset、endContainer、endOffset、commonAncestorContainer这些选区属性

    用DOM范围实现复杂选择

    当我们需要更加复杂的选区,比如我们需要选择某个节点的一部分时

    要创建这样复杂的节点,则需要使用 setStart()和 setEnd()来分别设置范围的起止位置

    这两个方法都接收两个参数:

    1.DOM节点

    2.开始/结束位置在节点中的偏移量

    同样下方的HTML代码为例

    <p id = "p1"><b>hello</b>world!</p>

    这里我们使用setStart()和 setEnd()来实现之前的range1、range2

    即如下方代码所示:

    var range1 = document.createRange();
    var range2 = document.createRange();
    var p1 = document.getElementById('p1');
    var Index = -1;//用于表示p1在其父节点中的偏移
    
    for(let i = 0,len = p1.parentNode.childNodes.length;i<len;i++){
        if(p1.parentNode.childNodes[i] === p1){
            Index = i;
            break;
        }
    }
    
    range1.setStart(p1.parentNode, Index);
    range1.setEnd(p1.parentNode, Index+1);
    range2.setStart(p1, 0);
    range2.setEnd(p1, p1.childNodes.length);
  • 相关阅读:
    反编译乱码对比
    ABP缓存写法
    AutoMapperHelper
    读取硬盘SN
    wpf用Prism里控件事件绑定mvvm
    ajax请求.net后台接收
    网站博客截取简介
    C# datetime.now.tostring("yyyy/MM/dd") 显示为yyyy-MM-dd的解决办法
    html5远程控制
    SmartThreadPool
  • 原文地址:https://www.cnblogs.com/lhyxq/p/10352491.html
Copyright © 2020-2023  润新知