美文网首页
2019-01-14

2019-01-14

作者: kathyever | 来源:发表于2019-01-14 21:07 被阅读0次

    12.4 范围

    为了让开发人员更方便的控制页面,“DOM2级遍历和范围”模块定义了“范围”(range)接口。通过范围可以选择文档中的一个区域,而不必考虑节点的界限(选择在后台完成,对用户是不可见的。)在常规的DOM操作不能更有效的修改文档时,使用范围往往可以达到目的。

    12.4.1 DOM中的范围

    DOM2级在Document类型中定义了createRange()方法。在兼容DOM的浏览器中,这个方法属于document对象。使用hasFeature()或者直接检测该方法都可以确定浏览器是否支持范围。
    如果支持就可以使用createRang()来创建DOM范围:

    var range = document.createRange();
    

    与节点类似,新创建的范围也应该与创建它的文档关联在一起,不能用于其他文档。创建了范围之后,接下来就可以使用它在后台选择文档中的特定部分。
    而创建范围并设置了其位置之后,还可以针对范围的内容执行很多种操作,从而实现对底层DOM树的更精细的控制。
    每个范围由一个Range类型的实例标识,这个实例拥有很多属性和方法。在把范围放到文档中特定的位置时,这些属性都会被赋值:

    1、用DOM范围实现简单选择

    要使用范围来选择文档中的一部分,最简单的方式就是使用selectNode()或selectNodeContents()。这两个方法都接受一个参数,即一个DOM节点,然后使用该节点中的信息来填充范围。
    ◆ selectNode()方法选择整个节点,包含其子节点
    ◆ selectNodeContents()方法则只选择节点的子节点

    <!DOCTYPE>
    <html>
        <body>
            <p id="p1"><b>Hello</b></p>
        </body>
    
        <script type="text/javascript">
            var range1 = document.createRange();//rang1包含<p/>元素及其所有子元素
                  range2 = document.createRange();//rang2包含<br/>元素、文本节点“Hello”和文本节点"world"
                  p1 = document.getElementById("p1");
            range1.selectNode(p1);
            range2.selectNodeCounts(p1);
        </script>
    
    </html>
    
    
    image.png
    2、用DOM范围实现复杂选择

    要创建复杂的范围就得使用setStart()和setEnd()方法。
    这两个方法都接受两个参数:一个参照节点和一个偏移量值。
    ◆ setStart():参照节点会变成startContainer,而偏移量值会变成startOffset
    ◆ setEnd():参照节点会变成endContainer,而偏移量值会变成endOffset。

    3、操作DOM范围中的内容

    ◆ deleteContents():这个方法能够从文档中删除范围所包含的内容
    ◆ extractContents():与deleteContents方法相似,也会从文档中移除范围选取。但这两个方法的区别在于,extractContents()会返回范围的文档片段。利用这个返回的值,可以将范围的内容插入到文档中的其他地方。
    ◆ cloneContents():使用此方法创建范围对象的一个副本,然后在文档的其他地方出入该副本。与extractContents()类似,都返回文档片段。主要的区别在于,cloneContents返回的文档片段包含的是范围中节点的副本,而不是实际的节点。

    4、插入DOM范围中的内容

    使用insertNode()方法可以向范围选取的开始处插入一个节点

    5、折叠DOM范围

    所谓折叠范围,就是指范围中未选择文档的任何部分。可以用文本框来描述折叠范围的过程。
    使用collapse()方法来折叠范围,这个方法接收一个参数,一个布尔值,表示要折叠到范围的哪一端。参数true表示折叠范围的起点,false表示终点。要确定范围已经折叠完毕,可以检查collapsed属性。

    range.collapse(true);//折叠到起点
    alert(range.collapsed);//输出true
    
    6、比较DOM范围

    在多个范围的情况下,使用compareBoundaryPoints()方法来确定这些范围是否有公共的边界(起点或终点)
    这个方法接受两个参数:表示比较方式的常量值和要比较的范围。

    7、复制DOM范围

    使用cloneRange()方法复制范围。这个方法会创建调用它的范围的一个副本

    var newRange=range.cloneRange();
    //新创建的范围与原来的范围包含相同的属性,而修改它的端点不会影响到原来的范围
    
    8、清理DOM范围

    调用dach()方法,以便从创建范围的文档中分离出该范围。
    调用detach()之后,就可以放心的解除对范围的引用,从而让垃圾回收机制回收其内存了。

    range.detach();//从文档中分离
    range=null;//解除引用。
    //一旦分离范围,就不能再恢复使用了。
    

    ————————————————————————————————

    global对象

    ES5的顶层对象,本身也是一个问题,因为它在各种实现里面是不统一的。

    ◆ 浏览器里面,顶层对象是window,但Node和Web Worker没有window。
    ◆ 浏览器和Web Worker里面,self也指向顶层对象,但是Node没有self。
    ◆ Node里面,顶层对象是global,但其他环境都不支持。

    为了能在各种环境中,同段代码能取到顶层对象,一般使用this变量,但是有局限性。

    ◆ 全局环境中,this会返回顶层对象。但是,Node模块和ES6模块中,this返回的是当前模块
    ◆ 函数里面的this,如果函数不是作为对象的方法运行,而是单纯作为函数运行,this会指向顶层对象。但是,严格模式下,这时this会返回undefined
    ◆ 不管是严格模式,还是普通模式,new Function(‘return this’)(),总是会返回全局对象。但是,如果浏览器使用了CSP(Content Security Policy,内容安全策略。),那么eval、new Function这些方法都可能无法使用。

    综上所述,很难找到一种方法,可以在所有情况下,都取到顶层对象。
    有一提案,在语言标准的层面,引入global作为顶层对象。也就是说,在所有环境下,global都是存在的,都可以从它拿到顶层对象。

    //CommonJS的写法
    var global = require('system.global')();
    
    //ES6 模块的写法
    import getGlobal from 'system.global';
    const global=getGlobal();
    
    //上面代码将顶层对象放入变量global
    

    相关文章

      网友评论

          本文标题:2019-01-14

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