DOM Range Api
Range Api 1
(必要的 api)
- var range = new Range();
- range.setStart(element, 9);
- range.setEnd(element, 4);
- var range = document.getSelection().getRangeAt(0);
也就是说,range 有两种创建方式
第一种,new Range()然后 setStart、setEnd
第二种,getSelection 然后 getRangeAt
Range Api 2
(可选的,方便 DOM 操作的 api)
针对单个node 的操作
- range.setStartBefore
- range.setEndBefore
- range.setStartAfter
- range.setEndAfter
- range.selectNode
- range.selectNodeContents
Range Api 3
(拿到 range 了以后可以做的事情)
-
var fragment = range.extractContents()
fragment 其实是一种文档的片段,当我们 append 一个 fragment 到 DOM 树的时候,append 上去的玩意儿其实是 fragment 里面的所有子元素,而 fragment 并没有挂载到 DOM 树中。
-
range.insertNode(document.createTextNode("aaa"))
我们使用 document.insertBefore 和 document.appendChild 的时候,只能在两个元素之间或者前后插入元素,而无法精确操作。(元素跟元素之间)
当使用 range.insertNode的时候,我们可以精确到两个 DOM 之间的具体的 text 中的位置,在该位置插入一个 Node。(文本跟文本之间)
上面这两个 api 的配合使用,有奇效。
实战
eg1
<div id="a">
<span>1</span>
<p>2</p>
<a>3</a>
<div>4</div>
</div>
<script>
let element = document.getElementById("a");
function reverseChildren() {
let range = new Range();
range.selectNodeContents(element);
let fragment = range.extractContents();
var l = fragment.childNodes.length;
while(l-- > 0) {
fragment.appendChild(fragment.childNodes[l]);
}
element.appendChild(fragment);
}
reverseChildren();
</script>
eg2
<div id="a">
123456789
</div>
<script>
let element = document.getElementById('a');
let range = new Range();
range.setStart(element, 0);
range.setEnd(element, 1);
console.log(range);
range.extractContent();
</script>
eg3
<div id="a">
123456789
</div>
<script>
let element = document.getElementById("a").childNodes[0];
let range = new Range();
range.setStart(element, 0);
range.setEnd(element, 4);
console.log(range);
range.extractContents();
</script>
eg4
<div id="a">
12345<span style="background-color: aqua;">456789</span>01111111111
</div>
<script>
let range = new Range();
range.setStart(document.getElementById("a").childNodes[1].childNodes[0], 0);
range.setEnd(document.getElementById("a").childNodes[2], 3);
// range.extractContents();
</script>
做富文本编辑器的时候,rangeApi 也很有用,省得光标去乱跳。
不过一般来说,我们也用不到富文本编辑器。
据说,做富文本编辑器,可以到阿里的 p7 的水准了。
不仅仅是一个 DOM 操作,这是一个很复杂的操作