从Range中插入一些数据
前一节的几个方法解决了如何移除range中所选中的fragment。现在说明如何添加内容到Range中。
insertNode()方法可以插入一个节点到Range中。假如我想把以下的节点插如Range中,将如何操作呢?
<span style="color: red">Inserted text</span>
看下面的代码:
01 | <p id= "p1" ><b>Hello</b> World</p> |
03 | var oP1 = document.getElementById( "p1" ); |
04 | var oHello = oP1.firstChild.firstChild; |
05 | var oWorld = oP1.lastChild; |
06 | var oRange = document.createRange(); |
07 | var oSpan = document.createElement( "span" ); |
08 | oSpan.style.color = "red" ; |
09 | oSpan.appendChild(document.createTextNode( "Inserted text" )); |
11 | oRange.setStart(oHello, 2); |
12 | oRange.setEnd(oWorld, 3); |
13 | oRange.insertNode(oSpan); |
那么原来的HTML将会变成这样:
<p id="p1"><b>He<span style="color: red">Inserted text</span>llo</b> World</p>
surroundContents()的参数为一个node,它将这个node加入到Range,下面看这个示例。
01 | <p id= "p1" ><b>Hello</b> World</p> |
03 | var oP1 = document.getElementById( "p1" ); |
04 | var oHello = oP1.firstChild.firstChild; |
05 | var oWorld = oP1.lastChild; |
06 | var oRange = document.createRange(); |
07 | var oSpan = document.createElement( "span" ); |
08 | oSpan.style.backgroundColor = "yellow" ; |
10 | oRange.setStart(oHello, 2); |
11 | oRange.setEnd(oWorld, 3); |
12 | oRange.surroundContents(oSpan); |
在oRange选取的范围内有一个我们新生成的节点span,因此选取的Range的背景变成了黄色。
collapse()方法:
collapse()方法只有一个布尔型的参数,该参数为可选的,也就是说,可以有,也可以没有,默认为false。
true时折叠到Range边界的首部,为false时折叠到Range尾部。即
01 | <p id= "p1" ><b>Hello</b> World</p> |
03 | var oP1 = document.getElementById( "p1" ); |
04 | var oHello = oP1.firstChild.firstChild; |
05 | var oWorld = oP1.lastChild; |
06 | var oRange = document.createRange(); |
07 | oRange.setStart(oHello, 2); |
08 | oRange.setEnd(oWorld, 3); |
如果你想知道该Range是否已经折叠,可以用collapsed属性来得到true或者false。看下面的例子。
1 | <p id= "p1" >Paragraph 1</p><p id= "p2" >Paragraph 2</p> |
3 | var oP1 = document.getElementById( "p1" ); |
4 | var oP2 = document.getElementById( "p2" ); |
5 | var oRange = document.createRange(); |
6 | oRange.setStartAfter(oP1); |
7 | oRange.setStartBefore(oP2); |
8 | alert(oRange.collapsed); |
上面的代码输为true。虽然我们没有用collapse方法,但是由于我们的Range设置开始为1末端到p2的首端,没有任何元素。即</p>(Range开始)(Range结束)<p id="p2">,所以显示的是true。
Range边界的比较
compareBoundaryPoints()方法,语法形式如下:
compare = comparerange.compareBoundaryPoints(how,sourceRange)
参数含义:
compare —— 返回1, 0, -1.(0为相等,1为时,comparerange在sourceRange之后,-1为comparerange在sourceRange之前)
how —— 为Range常数:END_TO_END|END_TO_START|START_TO_END|START_TO_START
sourceRange —— 一个Range对象的边界。
看下面的例子:
01 | <p id= "p1" ><b>Hello</b> World</p> |
03 | var oRange1 = document.createRange(); |
04 | var oRange2 = document.createRange(); |
05 | var oP1 = document.getElementById( "p1" ); |
06 | oRange1.selectNodeContents(oP1); |
07 | oRange2.selectNodeContents(oP1); |
08 | oRange2.setEndBefore(oP1.lastChild); |
09 | alert(oRange1.compareBoundaryPoints(Range.START_TO_START, oRange2)); |
11 | alert(oRange1.compareBoundaryPoints(Range.END_TO_END, oRange2)); |
下图为这两个Range的示意图,结合代码和上面的说明,可以清晰的分析出结果了。
克隆(clone)Range
这个操作很简单,只需要一句语句即可:
1 | var oNewRange = oRange.cloneRange(); |
cloneRange()方法将返回一个当前Range的副本,当然,它也是Range对象。
清除Range所占的系统资源
当你创建了Range对象最好用detach()方法来清除它所占的系统资源。虽然不清除,GC(垃圾收集器)也会将其收集,但用detach()释放是一个好习惯。语法为:
下面一个示例在Mozilla中,利用Range可以模拟出IE中的element.insertAdjacentHTML()方法
01 | if (browser.isMozilla) { |
02 | HTMLElement.prototype.insertAdjacentHTML = function (sWhere, sHTML) { |
03 | var df; var r = this .ownerDocument.createRange(); |
04 | switch (String(sWhere).toLowerCase()) { |
06 | r.setStartBefore( this ); |
07 | df = r.createContextualFragment(sHTML); |
08 | this .parentNode.insertBefore(df, this ); |
11 | r.selectNodeContents( this ); |
13 | df = r.createContextualFragment(sHTML); |
14 | this .insertBefore(df, this .firstChild); |
17 | r.selectNodeContents( this ); |
19 | df = r.createContextualFragment(sHTML); |
23 | r.setStartAfter( this ); |
24 | df = r.createContextualFragment(sHTML); |
25 | this .parentNode.insertBefore(df, this .nextSibling); |
参考文档:
Professional JavaScript for Web Developers(Wrox)
Mozilla Develop Center Document
原文地址
------------------------------
最后给出一版很好用的兼容IE insertAdjacentHTML方法 具体解析待续:
02 | if (document.documentElement.insertAdjacentHTML){ return ;} |
03 | HTMLElement.prototype.insertAdjacentHTML = function (sWhere, sHTML){ |
04 | var df = null ,r = this .ownerDocument.createRange(); |
05 | switch (String(sWhere).toLowerCase()) { |
07 | r.setStartBefore( this ); |
08 | df = r.createContextualFragment(sHTML); |
09 | this .parentNode.insertBefore(df, this ); |
12 | r.selectNodeContents( this ); |
14 | df = r.createContextualFragment(sHTML); |
15 | this .insertBefore(df, this .firstChild); |
18 | r.selectNodeContents( this ); |
20 | df = r.createContextualFragment(sHTML); |
24 | r.setStartAfter( this ); |
25 | df = r.createContextualFragment(sHTML); |
26 | this .parentNode.insertBefore(df, this .nextSibling); |