1.遍历Dom节点的两种方法
1)nodeList (该方法会将空格视为节点)
相关属性有:
- 父节点 parentNode
- 第一个子节点 firstChild
- 最后一个子节点 lastChild
- 子节点们 childNodes
- html文档的根节点 document.documentElement
- 根节点 ownerDocument
- 前节点 previousSibling
- 后节点 nextSibling
- 返回Dom的标签名 tagName
- 返回是否拥有子节点 hasChildNodes()
childNodes是一个类数组,可以使用索引访问,如 obj.childNodes[1],也可以使用item(index)方法访问,如obj.childNodes.item(1)
<body>
<!-- 父节点 第一个子节点 最后一个子节点 子节点 > 使用索引 > 使用item(index)
文档的根节点 根节点 前节点 后节点 返回标签名 返回是否拥有子节点 -->
//该方法会将Dom之间的空格当作text Dom,故标签之间没有空格和换行
<div id="box"><h1>li节点1</h1><h5>li节点2</h5><p>li节点3</p></div>
<div><h1>这是一个一号标题</h1><h5 id="h5">这是一个五号标题</h5><p>这是一个段落</p></div>
<script>
var ohtml = document.documentElement;
var box = document.getElementById("box");
var objNode = document.getElementById("h5");
console.log("box Dom的标签名为:" + box.tagName);
console.log("box Dom的第一个子节点是" + box.firstChild.tagName);
console.log("box Dom的最后一个子节点是" + box.lastChild.tagName);
console.log("box Dom的第二个节点是:" + box.childNodes[1].tagName);
console.log("box Dom的第二个节点是:" + box.childNodes.item(1).tagName);
console.log("文档的根节点是:" + ohtml.tagName);
console.log("box Dom的根节点是:" + box.ownerDocument);
console.log("box Dom的父节点是:" + box.parentNode.tagName);
console.log("id 为 h5 的Dom 标签是" + objNode.tagName);
console.log('id为h5的Dom 标签名为:'+objNode.tagName)
console.log('id为h5的Dom 的前一个兄弟节点标签名为:'+objNode.previousSibling.tagName)
console.log('id为h5的Dom 的后一个兄弟节点标签名为:'+objNode.nextSibling.tagName)
console.log('id为h5的Dom有子节点吗?'+objNode.hasChildNodes())
console.log(objNode.childNodes)
</script>
</body>
2)children(该方法不会将空格当作Dom,但对浏览器有版本要求)
相关属性有:
- 第一个子节点 firstElementChild
- 最后一个子节点 lastElementChild
- 子节点们 children
- 前节点 previousElementSibling
- 后节点 nextElementSibling
children是一个类数组,可以使用索引访问,如 obj.children[1]
两种遍历Dom节点的方法略有不同,可以对比,后者在前者的基础之上多了一个Element,毕竟后者是之后出来的,相当于是前者的升级版
<body>
<ul id="box">
<li>这是文本1</li>
<li>这是文本2</li>
<li>这是文本3</li>
</ul>
<p id="heading">这是一个段落</p>
<script>
var box = document.getElementById("box");
var len = box.children.length;
for (var i = 0; i < len; i++) {
console.log(box.children[i]);
}
var ohtml = document.documentElement;
console.log(ohtml);
// 这两行内容等同于下面注释掉的两行代码
var obody = ohtml.children[1];
var ohead = obody.previousElementSibling;
// var ohead=ohtml.firstElementChild;
// var obody=ohtml.lastElementChild;
console.log("ohead:" + ohead.tagName);
console.log("obody:" + obody.tagName);
var box = document.getElementById("box");
console.log("box节点的子节点数量是:" + box.children.length);
var node1 = document.getElementById("heading");
var node2 = node1.previousElementSibling;
console.log("测试previousElementSibling:" + node2.tagName);
</script>
</body>
2.类数组对象
类数组对象是指,可以像js的数组那样通过 [index] 访问,但不具有数组的push等方法
- 上面的NodeList
- HTML Collection
- NamdeNodeMap
HTML Collection包括但不限于以下内容:
- document.links
- document.scripts
- document.images
- document.forms
- dom.options
- tr.cells
- getElementByTagName
//这里的domReady.js文件的作用是,js代码写在head标签中仍然可以正常执行,末尾可以下载
<script src="../js/domReady.js"></script>
<script>
myReady(function(){
var scripts = document.scripts;
var links = document.links;
var cells = document.getElementById('tr').cells;
var imgs = document.images;
var forms = document.forms;
var options = document.getElementById('select').options;
var ps = document.getElementsByTagName('p')
console.log(scripts);
console.log(links);
console.log(cells);
console.log(imgs); ;
console.log(forms);
console.log(options);
console.log(ps);
})
</script>
</head>
<body>
<ul id="box">
<li>>节点1</li>
<li>>节点2</li>
<li>>节点3</li>
<ul>
<table border="1">
<tr id="tr">
<td>第一行</td>
<td>第二行</td>
<td>第三行</td>
</tr>
</table>
<img src="../pictures/img1.png" alt="img1" />
<img src="../pictures//飞天.jpg" alt="img2" />
<form action="">
<input type="text" value="用户名">
</form>
<form action="">
<input type="text" value="密码">
</form>
<a href="#">忘记密码</a>
<a href="#">更多内容</a>
<select id="select">
<option value="0">北京</option>
<option value="1">天津</option>
<option value="2">河北</option>
</select>
<p>Dom探索之基础详解篇</p>
<p>Dom之节点操作篇</p>
</body>
</html>
NamdeNodeMap是指html标签中的属性
<body>
<ul id="box" data-url="index.html" node-action="submit">
<li>节点一</li>
<li>节点二</li>
<li>节点三</li>
</ul>
<p></p>
<script>
var box = document.getElementById("box");
var attrs = box.attributes;
console.log(attrs);
console.log(attrs[1]);
</script>
</body>
3.类数组对象的动态性
类数组对象的动态性是指,这些类对象数组的长度会随着html结构的改变而自动改变
例如下面这个例子
<head>
<meta charset="UTF-8" />
<title>Document</title>
<script src="../js/domReady.js"></script>
<script>
myReady(function() {
//获取类数组对象
var divs = document.getElementsByTagName("div");
var i = 0;
while (i < divs.length) {
//目的是再创建三对div标签
//创建节点
document.body.appendChild(document.createElement("div"));
i++;
}
});
</script>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
但运行文件会发现,没有得到想要的结果,这是因为,
var divs = document.getElementsByTagName(“div”);
这一句得到了一个类数组对象,而该类数组的长度会随着while循环中创建新的div而自动增加长度,因此程序会陷入一个死循环
因此需要使用一个变量存储最原始的类数组对象的长度,即改为下面这样
<head>
<meta charset="UTF-8" />
<title>Document</title>
<script src="../js/domReady.js"></script>
<script>
myReady(function() {
//获取类数组对象
var divs = document.getElementsByTagName("div");
var i = 0;
//使用一个变量存储原始divs的长度
var length = divs.length;
while (i < length) {
//目的是再创建三对div标签
//创建节点
document.body.appendChild(document.createElement("div"));
i++;
}
});
</script>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
这样就可得到想要的结果
文中使用到的 myReady 文件:
function myReady(fn){
//对于现代浏览器,对DOMContentLoaded事件的处理采用标准的事件绑定方式
if ( document.addEventListener ) {
document.addEventListener("DOMContentLoaded", fn, false);
} else {
IEContentLoaded(fn);
}
//IE模拟DOMContentLoaded
function IEContentLoaded (fn) {
var d = window.document;
var done = false;
//只执行一次用户的回调函数init()
var init = function () {
if (!done) {
done = true;
fn();
}
};
(function () {
try {
// DOM树未创建完之前调用doScroll会抛出错误
d.documentElement.doScroll('left');
} catch (e) {
//延迟再试一次~
setTimeout(arguments.callee, 50);
return;
}
// 没有错误就表示DOM树创建完毕,然后立马执行用户回调
init();
})();
//监听document的加载状态
d.onreadystatechange = function() {
// 如果用户是在domReady之后绑定的函数,就立马执行
if (d.readyState == 'complete') {
d.onreadystatechange = null;
init();
}
}
}
}