• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >JavaScript > 详解Javascript中DOM的范围

详解Javascript中DOM的范围

作者:小火柴的蓝色理想 字体:[增加 减小] 来源:互联网 时间:2017-05-11

小火柴的蓝色理想通过本文主要向大家介绍了javascript dom操作,javascript dom编程,javascript dom手册,dom javascript,javascript dom对象等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

前言

为了让开发人员更方便地控制页面,DOM定义了“范围”(range)接口。通过范围可以选择文档中的一个区域,而不必考虑节点的界限(选择在后台完成,对用户是不可见的)。在常规的DOM操作不能更有效地修改文挡时,使用范围往往可以达到目的。本文将详细介绍DOM范围,下面来一起看看吧。

创建范围

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

[注意]IE8-浏览器不支持

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

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

var range = document.createRange();
</div>

与节点类似,新创建的范围也直接与创建它的文档关联在一起,不能用于其他文档。创建了范围之后,接下来就可以使用它在后台选择文档中的特定部分。而创建范围并设置了其位置之后,还可以针对范围的内容执行很多种操作,从而实现对底层DOM树的更精细的控制

每个范围由一个Range类型的实例表示,这个实例拥有很多属性和方法。

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

  • startContainer:包含范围起点的节点(即选区中第一个节点的父节点)
  • startoffset:范围在startContainer中起点的偏移量。如果startContainer是文本节点、注释节点或CDATA节点,那么startoffset就是范围起点之前跳过的字符数量。否则,startoffset就是范围中第一个子节点的索引
  • endContainer:包含范围终点的节点(即选区中最后一个节点的父节点)
  • endOffset:范围在endContainer中终点的偏移量(与startoffset遵循相同的取值规则)
  • commonAncestorContainer:startContainer和endContainer共同的祖先节点在文档树中位置最深的那个

在把范围放到文档中特定的位置时,这些属性都会被赋值

简单选择

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

<!DOCTYPE html>
<html>
 <body>
 <p id="p1"><b>Hello</b> world!</p>
 </body>
</html>
</div>

我们可以使用下列代码来创建范围

var range1 = document.createRange();
var range2 = document.createRange();
var p1 = document.getElementById("p1");
//Range {startContainer: body, startOffset: 1, endContainer: body, endOffset: 2, collapsed: false…}
range1.selectNode(p1);
//Range {startContainer: p#p1, startOffset: 0, endContainer: p#p1, endOffset: 2, collapsed: false…}
range2.selectNodeContents(p1);
</div>

这里创建的两个范围包含文档中不同的部分:rangl包含<p>元素及其所有子元素,而rang2包含<b>元素、文本节点"Hello"和文本节点"world!"

在调用selectNode()时,startContainer、endContainer和commonAncestorContainer都等于传入节点的父节点,也就是这个例子中的document.body。而startoffset属性等于给定节点在其父节点的childNodes集合中的索引(在这个例子中是1——因为兼容DOM的浏览器将空格算作一个文本节点),endOffset等于startoffset加1(因为只选择了一个节点)

在调用selectNodeContents()时,startContainer、endContainer和commonAncestorContainer等于传入的节点,即这个例子中的<p>元素。而startoffset属性始终等于0,因为范围从给定节点的第一个子节点开始。最后,endOffset等于子节点的数量(node.childNodes.length),在这个例子中是2

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

  1. setStartBefore(refNode) :将范围的起点设置在refNode之前,因此refNode也就是范围选区中的第一个子节点。同时会将startContainer属性设置为refNode.parentNode,将startoffset属性设置为refNode在其父节点的childNodes集合中的索引
  2. setStartAfter(refNode) :将范围的起点设置在refNode之后,因此refNode也就不在范围之内了,其下一个同辈节点才是范围选区中的第一个子节点。同时会将startContainer属性设置为refNode.parentNode,将startoffset属性设置为refNode在其父节点的childNodes集合中的索引加1
  3. setEndBefore(refNode) :将范围的终点设置在refNode之前,因此refNode也就不在范围之内了,其上一个同辈节点才是范围选区中的最后一个子节点。同时会将endContainer属性设置为refNode.parentNode,将endOffset属性设置为refNode在其父节点的childNodes集合中的索引
  4. setEndAfter(refNode) :将范围的终点设置在refNode之后,因此refNode也就是范围选区中的最后一个子节点。同时会将endContainer属性设置为refNode.parentNode,将endOffset属性设置为refNode在其父节点的childNodes集合中的索引加1

调用这些方法时,所有属性会自动设置好。不过,要想创建复杂的范围选区,也可以直接指定这些属性的值

复杂选择

要创建复杂的范围就得使用setStart()和setEnd()方法。这两个方法都接受两个参数:一个参照节点和一个偏移量值。对setStart()来说,参照节点会变成startContainer。而偏移量值会变成startoffset。对于setEnd()来说,参照节点会变成endContainer,而偏移量值会变成endOffset。可以使用这两个方法来模仿selectNode()和selectNodeContents() 。

来看下面的例子

var range1 = document.createRange();
var range2 = document.createRange();
var p1 = document.getElementById("p1"); 
var p1Index = -1;
var i, len;
 
for (i=0, len=p1.parentNode.childNodes.length; i < len; i++) {
 if (p1.parentNode.childNodes[i] == p1) {
 p1Index = i;
 break;
 }
}
 
range1.setStart(p1.parentNode, p1Index);
range1.setEnd(p1.parentNode, p1Index + 1);
range2.setStart(p1, 0);
range2.setEnd(p1, p1.childNodes.length);
</div>

显然,要选择这个节点(使用range1),就必须确定当前节点(p1)在其父节点的childNodes集合中的索引。而要选择这个节点的内容(使用range2),也不必计算什么;只要通过setStart()和setEnd()设置默认值即可。模仿selectNode()和selectNodeContents()并不是setStart()和setEnd()的主要用途,它们更胜一筹的地方在于能够选择节点的一部分

假设只想选择前面HTML示例代码中从“Hello"的"llo"到"world!"的"o"——很容易做到

第一步是取得所有节点的引用,如下所示:

var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChild;
var worldNode = p1.lastChild;
</div>

实际上,"Hello”文本节点是<p>元素的孙子节点,因为它本身是<b>元素的一个子节点。因此,p1.firstchild取得的是<b>,而p1.firstchild.firstchild取得的才是这个文本节点。"world!"文本节点是<p>元素的第二个子节点(也是最后一个子节点),因此可以使用p1.lastChild取得该节点。

然后,必须在创建范围时指定相应的起点和终点,如下所示

var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
</div>

因为这个范围的选区应该从"Hello"中"e"的后面开始,所以在setStart()中传入helloNode的同时,传入了偏移量2(即"e"的下一个位置;"H"的位置是0)。设置选区的终点时,在setEnd()中传入worldNode的同时传入了偏移量3,表示选区之外的第一个字符的位置,这个字符是”r",它的位置是3(位置0上还有一个空格)。

如下所示

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • JavaScript中 DOM操作方法小结
  • Javascript操作dom对象之select全面解析
  • JavaScript结合HTML DOM实现联动菜单
  • 详解Javascript中DOM的范围
  • JavaScript基于Dom操作实现查找、修改HTML元素的内容及属性的方法
  • Javascript DOM事件操作小结(监听鼠标点击、释放,悬停、离开等)
  • JavaScript DOM节点操作实例小结(新建,删除HTML元素)
  • javascript判断元素存在和判断元素存在于实时的dom中的方法
  • JavaScript基于DOM操作实现简单的数学运算功能示例

相关文章

  • 2017-05-11JavaScript实现实时更新系统时间的实例代码
  • 2017-05-11jQuery使用siblings获取某元素所有同辈(兄弟姐妹)元素用法示例
  • 2017-05-11javascript 动态生成css代码的两种方法
  • 2017-05-11bootstrap下拉菜单使用方法解析
  • 2017-05-11JS ES6多行字符串与连接字符串的表示方法
  • 2017-05-11js以及jquery实现手风琴效果
  • 2017-05-11Node.js与Sails redis组件的使用教程
  • 2017-05-11js 去掉字符串前后空格实现代码集合
  • 2017-05-11jquery滚动条插件slimScroll使用方法
  • 2017-05-11JQuery查找子元素find()和遍历集合each的方法总结

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • bootstrap table实例详解
    • bootstrap datetimepicker实现秒钟选择下拉框
    • jQuery表单元素选择器代码实例
    • JS实现本地存储信息的方法(基于localStorage与userData)
    • js运算符
    • js基于myFocus实现轮播图效果
    • Angular.js 4.x中表单Template-Driven Forms详解
    • Javascript中字符串和数字的操作方法整理
    • 详解Angular 4.x 动态创建组件
    • BootStrap3中模态对话框的使用

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有