DOM1级主要定义的是HTML和XML文档的底层结构。2和3在此基础上引入了更多的交互能力,支持更高级的XML特性。
样式
HTML中有三种定义样式的方法:通过link元素包含外部样式文件,style元素定义嵌入式,style特性定义特定元素的样式。
var div = document.getElementById('mydiv');
//通过div的style属性设置背景颜色
div.style.backgroundColor = 'pink';
//改变div的大小
div.style.width = '200px';
div.style.height = '100px';
//指定边框
div.style.border = "1px solid black";
//通过访问cssText属性可以访问style特性中的CSS代码,也可以通过它重写样式
div.style.cssText = "width: 400px; height: 200px; background-color: green";
// console.log(div.style.cssText);
//迭代取出元素中定义的css属性名和值
for (let i = 0, len = div.style.length; i < len; i++) {
// console.log(div.style[i]);
prop = div.style[i];
value = div.style.getPropertyValue(prop);
console.log(prop + ": " + value);
}
样式的计算
当同时使用多种CSS样式定义方式时,比如,style元素定义嵌入式和style属性同时使用,需要计算出最终执行的CSS样式,DOM2级提供了getComputedStyle的方法,
var computedStyle = document.defaultView.getComputedStyle(div, null);
console.log(computedStyle.backgroundColor);
console.log(computedStyle.width);
操作样式标
文档的所有样式表都可以通过document.styleSheets集合来获取,可以通过length属性获得文档中样式表的数量,href属性获得link标签中的url,
CSSRule对象表示样式表中的每一条规则, 该对象中最常用的三种属性为:cssText属性,返回整条规则对应的文本,只读;selectorText返回当前规则的选择符文本;style 可以通过设置它取得规则中特定的样式。
还可以向样式表中添加新规则,使用insertRule方法,使用deleteRule删除规则。
offsetHeight, offsetWidth, offsetLeft, offsetTop四个属性可以用来确定元素的大小。
遍历DOM
NodeIterator 和 TreeWalker 两种方法都可以遍历DOM结构。前者较为简单,只允许以一个节点的步幅前后移动,后者为前者的高级版本,支持在DOM结构的各个方向上移动,包括父节点,同辈节点和子节点。
//想要遍历div标签中的所有元素
let div = document.getElementById('div1');
let iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT,
null, false);
let node = iterator.nextNode();
while (node !== null) {
console.log(node.tagName);
node = iterator.nextNode();
}
//只返回遇到的Li元素,设置filter函数,判断tagName是否是li来判断接受还是拒绝
let filter = function(node) {
return node.tagName.toLowerCase() == "li" ?
NodeFilter.FILTER_ACCEPT:
NodeFilter.FILTER_SKIP;
}
let iterator1 = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT,
filter, false);
let node1 = iterator1.nextNode();
while (node1 !== null) {
console.log(node1.tagName);
node1 = iterator1.nextNode();
}
范围
DOM2级还定义了范围接口,Document类型中的createRange()方法,可以自由选取文档中的一个区域,有简单选择和复杂选择两种方式。selectNode和selectNodeContents实现范围的简单选取,setStart和setEnd实现范围的复杂选取。
//selectNode 和 selectNodeContents方法实现范围的简单选取
let range1 = document.createRange(),
range2 = document.createRange(),
p1 = document.getElementById('p1');
range1.selectNode(p1),
range2.selectNodeContents(p1);
console.log(range1);
//setStart和setEnd实现复杂选取
let range1 = document.createRange(),
range2 = document.createRange(),
p1 = document.getElementById('p1'),
p1Index = -1,
i, len;
// console.log(p1.parentNode.childNodes);
//找到p1元素在父节点上所在的顺序
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);
//选择 hello 的 llo 到 world 中的 o
//p1元素子节点b元素的子节点 文本节点
let helloNode = p1.firstChild.firstChild;
// console.log(helloNode);
let worldNode = p1.lastChild;
//p1元素最后一个子节点 文本节点
// console.log(worldNode);
let range3 = document.createRange();
//hello文本节点的第二位
range3.setStart(helloNode, 2);
//world文本节点的第三位
range3.setEnd(worldNode, 3);
// console.log(range3);
操作DOM范围中的内容
还可以操作DOM范围中的内容,比如deletContents(删除),extractContents(选取), insertNode(插入节点)
//操作DOM范围中的内容
let fragment = range3.extractContents();
console.log(fragment); //返回一个文档片段
// range3.deleteContents(); //页面显示会改变
//还可以将返回的文档片段插入到文档中的其他地方
p1.parentNode.appendChild(fragment)
//还可以向DOM范围中插入内容,比如在此插入span标签
let span = document.createElement("span");
span.style.color = 'red';
//向span标签中插入文本节点
span.appendChild(document.createTextNode("Inserted text"));
//span节点插入到range3范围开始的地方
range3.insertNode(span);
//还可以选择环绕范围插入一些内容,使用surroundContents方法
//以下例子给所选范围添加黄色背景
let range4 = document.createRange();
range4.selectNode(helloNode);
let span1 = document.createElement('span');
span1.style.backgroundColor = 'yellow';
range4.surroundContents(span1)
折叠DOM范围
折叠范围,指范围中未选择文档的任何部分。一般使用collapse方法来折叠范围。检测某个范围是否处于折叠状态,可以帮助确认范围中的两个节点是否紧密相连:
//确定两个节点是否紧密相连
let p1 = document.getElementById('p1'),
p2 = document.getElementById('p2'),
range = document.createRange();
range.setStartAfter(p1);
range.setEndBefore(p2);
console.log(range.collapsed); //true 两个节点紧密相连
除此之外还可以比较,复制,清理DOM范围。在IE8及更早的版本不支持range对象,但是有类似的概念,即文本范围 textrange,也可以实现范围的选择,操作,折叠,复制,比较。