节点层次
节点分为几种不同的类型,每种类型分别表示文档中不同的信息或标志,每个节点拥有各自的特点,数据和方法,节点与其他节点之间存在某种关系。节点之间构成了层次。
Node类型
- js中所有的节点类型都继承自Node类型,因此所有的节点类型都共享着相同的基本属性和方法。
- 每个节点都有一个nodeType属性,用于表示节点的类型
- nodeType属性,用于表明节点的类型
if (some.nodeType == Node.ElEMENT_NODE){ // 节点类型p248 该方法在IE中无效
console.log('node is an element')
}
if(some.nodeType == 1){
console.log('node is an element') // 适用于所有的浏览器中
}
nodeName和nodeValue 属性
<body>
<div id="box"></div>
<script>
var oBox = document.getElementById('box');
console.log(box.nodeName); // DIV 保存的始终是元素的标签名
console.log(box.nodeType); // 1 识别到元素的类型
console.log(box.nodeValue); // null 始终为null
</script>
</body>
节点关系
- 每个节点包含childNodes属性,用于保存一组有序的节点,可以通过位置访问,有length属性,但是并不是Array实例
- NodeList对象可以自动反映DOM的节点变化,并不是瞬间固定的
<body>
<div id="box">
<a>1111111</a>
<a>222222222</a>
<a>3333333333</a>
<a>44444444444</a>
</div>
<script>
var oBox = document.getElementById('box');
for ( var i = 0; i < oBox.childNodes.length ; i ++){
console.log(oBox.childNodes[i].nodeName); // #text A #text A #text A #text A #text
}
//console.log(oBox.childNodes[1].nodeName);
// 这里只包含子节点,且包括文本节点(包括空格)
</script>
</body>
- 对arguments对象使用Array.prototype.slice()方法可以将其转化为数组,采用同样的方法,也可以将NodeList对象转化为数组
var arrayofNodes = Array.prototype.slice(someNode.childNodes,0) // IE8及以下不兼容
// IE8及以下版本
function convertToArray(nodes){
var array = null;
try{
array = Array.prototype.slice(nodes,0)
}catch(e){
array = new Array;
for ( var i = 0; i < nodes.length; i ++){
array.push(nodes[i])
}
}
return array;
}
-
children 只读属性子节点列表的集合
标准下: 只包含元素类型的节点,包含非法嵌套节点
非标准下: 只包含元素类型的节点,不包括非法嵌套 -
parentNode属性,指向文档树中的父节点
- 包含在childNodes列表中的所有节点具有相同的父节点
- 通过previousSibling和nextSibling属性,访问同一列表中的其他节点,第一子节点和最后一个子节点的previousSibling和nextSibling为null。如果只有一个字节点的话,都为null
- 父节点的lastChild和firstChild指向第一个和最后一个子节点,只有一个节点的话,lastChild和firstChild指向相同的节点,没有子节点,为null
firstChild 和 lastChild 标准下: 包含文本类型的节点
非标准下: 只包含元素节点
var oFirst = oUl.firstElmentChild || oUl.firstChild // 兼容
// 最好的解决方式 oUl.children[0].style.background = 'red';
var oNext = oBox.nextSibling || oBox.nextElementSibling;
var oPrev = oBox.previousSibling || oBox.previousElementSibling
操作节点
- appendChild(),用于向childNodes列表末尾添加节点,如果传入到appendChild()方法的节点是已经存在的,则改变了节点的位置
<div id="box">
<span class="span">span1</span>
<span class="span">span2</span>
<span class="span">span3</span>
</div>
<script>
var oBox = document.getElementById('box');
var aSpan = document.getElementsByTagName('span');
//var oSpan = document.getElementById('span');
oBox.onclick = function () {
oBox.appendChild(aSpan[0])
// 被放入的父元素.appendChild(元素) 改变了现有元素的排列顺利
// appendChild()操作的元素放入所有中的最后
}
</script>
- insertBefore() 接受两个参数,要插入的节点,和作为参考的节点,如果第二个参数不需要,则必须传入null,效果与appendChild()一样
<div id="box">
<span class="span">span1</span>
<span class="span">span2</span>
<span class="span">span3</span>
</div>
<script>
var oBox = document.getElementById('box');
var aSpan = document.getElementsByTagName('span');
//var oSpan = document.getElementById('span');
oBox.onclick = function () {
console.log('askdj')
oBox.insertBefore(aSpan[0],aSpan[2]) // 在aSpan[2]的位置前插入aSpan[0]
oBox.insertBefore(aSpan[0],null) // 效果与appendChild一致
console.log('afjkals')
}
</script>
- replaceChild() 接受两个参数,要插入的节点和替换的节点,要替换的节点将由这个方法返回并从文档中移除,同时由插入的节点占据其位置
<div id="box">
<span class="span" id="span">span0</span>
<span class="span">span1</span>
<span class="span">span2</span>
</div>
<script>
var oBox = document.getElementById('box');
var aSpan = document.getElementsByTagName('span');
var oSpan = document.getElementById('span');
//var oSpan = document.getElementById('span');
oBox.onclick = function () {
console.log('askdj')
oBox.replaceChild(aSpan[2],aSpan[0]) // aSpan[2]替换了aSpan[0]的位置,方法返回移除的节点
console.log('afjkals')
}
aSpan[2].onclick = function(){
alert(oSpan.innerHTML) // aSpan[0] 只是在文档中不存在这样位置了,但是节点仍然存在在文档中
}
</script>
- removeChild() 接受一个参数,即将要移除的节点,被移除的节点为这个方法的返回值
<div id="box">
<span class="span" id="span">span0</span>
<span class="span">span1</span>
<span class="span">span2</span>
</div>
<script>
var oBox = document.getElementById('box');
var aSpan = document.getElementsByTagName('span');
var oSpan = document.getElementById('span');
//var oSpan = document.getElementById('span');
oBox.onclick = function () {
oBox.removeChild(aSpan[0]) // 删除该节点,且文档中没有改节点的位置
}
</script>
Document 类型
- document表示整个HTML页面,document是window对象的一个属性
文档的子节点
- 页面经过浏览器的解析后,其文档只包含一个子节点,即html元素
var html = document.documentElement;
console.log(html === document.childNode[0]); // true
console.log(html === document.firstChild); // true
- document 对象还有一个body属性,直接指向body元素
var body = document.body; // 取得body的引用
文档信息
- title 通过这个属性可以取得到当前页面的标题
var oTitle = document.title; // 取得title
document.title = 'new'; // 设置title
- URL,domain,referrer
URL 包含页面完整的URL(地址栏中显示的URL),domain属性只包含页面的域名,而referrer包含链接到当前页面的那个页面的URL
查找元素
-
getElementById()
要注意大小写的匹配(IE8和较低版本不区分ID的大小写) -
getElementsByTagName() 接受一个参数,要取得元素的标签名
<div id="box">
<span class="span" id="span">span0</span>
<span class="span">span1</span>
<span class="span" name="mySpan">span2</span>
</div>
<script>
var oBox = document.getElementById('box');
var aSpan = document.getElementsByTagName('span'); // 将一个HTMLCollection对象保存在images变量中
</script>
HTMLCollection对象上还有一个方法,namedItem(),通过name特性取得相应的值
<div id="box">
<span class="span" id="span">span0</span>
<span class="span" name="mySpan">span1</span>
<span class="span" name="mySpan">span2</span>
</div>
<script>
var oBox = document.getElementById('box');
var aSpan = document.getElementsByTagName('span');
aSpan.namedItem('mySpan').innerHTML = 'yellow';
console.log(aSpan.namedItem('mySpan')); // 得到一个name是mySpan的元素
aSpan['mySpan'].innerHTML = '444'
</script>
要得到所有元素则传入''
var allEle = document.getElementsByTagName('')
-
getElementsByName()
返回一个NodeList,同样具有namedItem()方法,只会取得第一项 -
特殊集合
document.links 包含所有带href特性的<a>元素 -
DOM一致性检测 p259
console.log(document.implementation.hasFeature('XML','1.0'));
// 如果浏览器支持给定名称和版本功能,则该方法返回true
- 文档的写入 write(),writeln(),open(),close()
<body>
<script>
window.onload = function(){
console.log(document.implementation.hasFeature('XML','1.0'));
document.write('111111111111') // 重写页面中的所有元素,包括title等只有body中留有write中的内容
}
</script>
</body>
<script>
document.write('111111111111'); // 在页面中添加元素
</script>
Element类型
-
元素节点具有以下特征
nodeType = 1
nodeName 为元素的标签名
nodeValue 值为null -
访问元素的标签名,可以使用nodeName,也可以使用tagName,这两个属性返回相同的值
<div id="box">kasdjf</div>
<script>
var oBox = document.getElementById('box');
console.log(oBox.tagName); // 'DIV'
console.log(oBox.nodeName); // 'DIV'
if ( ele.tagName.toLowerCase() == 'div'){ // 适用于任何文档(XML,XHTML)
}
</script>
-
HTML 元素
- 元素中指定的信息,都可以通过下列方式获得
<div id="box" title="askldfj" dir="rtl" class="red" lang="en">kasdjf</div> <script> var oBox = document.getElementById('box'); console.log(oBox.id); // oBox.title oBox.dir oBox.className oBox.lang oBox.id = 'div' // 修改相关样式 console.log(oBox.style) // 打印出所有的style样式 </script>
-
取得特性 getAttribute()
<script> console.log(oBox.getAttribute('id')) console.log(oBox.getAttribute('class')); // 这种方式取得class属性传入的参数与实际的特性吗相同 </script>
- 特性名称并不区分大小写
- 根据H5规范,自定义的属性应该加上data-前缀一遍验证
-
设置属性 setAttritute()
- 接受两个参数,特性名和特性值,如果存在这样的值,则替换,如果特性不存在,则创建相应的值
div.setAttribute('id','someId')
//所有的特性都是属性
div.id = 'someId'
- 删除特性 removeAttribute()
- 不仅会删除特性的值,也会完全的删除特性
div.removeAttribute('class');
- attributes 属性
console.log(oBox.id);
console.log(oBox["id"]);
var id = ele.attribute['id'].nodeValue;
var id = element.attributes.getNamedItem('id').nodeValue; // 取得id的属性值
var oldAttr = ele.attributes.removeNamedItem('id');
console.log(oldAttr); // id="box"
- 创建元素
var div = document.createElement('div'); // 创建元素
div.id = 'div';
div.className = 'box'; // 设置属性
doucment.body.appendChild(div);
* IE7一些bug
* 不能设置iframe元素的name特性
* 不能通过reset()重设动态创建input元素
* 动态创建的type特性值为reset的button元素重设不了表单
* 动态创建的name相同的单选按钮毫无关系
```js
var iframe = document.createElement("<iframe name=\"myframe\"></iframe>")
var input = document.createElement("<input type=\"checkbox\">")
var radio = document.createElement("<input type=\"radio\" name=\"choice\">")
```
- 元素的子节点
<ul id="myList">
<li>kldjf</li>
<li>kldjf</li>
<li>kldjf</li>
</ul>
- 在IE中ul的childNodes包含3个子节点,只有3个li
- 在标准浏览器中,childNodes包含了7个子节点,3个li和li之间的空白符
DOM操作技术
操作表格
<script>
var table = document.createElement('table');
table.border = 1;
table.width = "100%";
var tbody = document.createElement('tbody');
table.appendChild(tbody);
tbody.insertRow(0); // 创建表格
tbody.rows[0].insertCell(0); // 第一行第一个单元格
tbody.rows[0].cells[0].appendChild(document.createTextNode("cell 1,1")); // 内容
tbody.rows[0].insertCell(1);
tbody.rows[0].cells[1].appendChild(document.createTextNode("cell 2,1"));
tbody.rows[0].insertCell(2);
tbody.rows[0].cells[2].appendChild(document.createTextNode("cell 2,2"));
tbody.insertRow(1);
tbody.rows[1].insertCell(0);
tbody.rows[1].cells[0].appendChild(document.createTextNode("cell 1,1"));
tbody.rows[1].insertCell(1);
tbody.rows[1].cells[1].appendChild(document.createTextNode("cell 2,1"));
tbody.rows[1].insertCell(2);
tbody.rows[1].cells[2].appendChild(document.createTextNode("cell 2,2"));
document.body.appendChild(table);
tbody.rows[0].cells[0] // 这种方法获得表格中的相应的单元格
</script>
网友评论