节点操作--父子节点
学习节点操作的目的还是为了获取元素,获取元素的常用 两种方式:
1.利用DOM提供的方法(API)获取元素
例如:document.getElementById();
或document.getElementByTagName();
或document.queyrSelector();
等
之前的这些方法很繁琐,且逻辑性不强
利用父子兄节点关系获取元素
逻辑性强,但是兼容性稍差
一般的,节点至少拥有nodeType(节点类型)和nodeName(节点名称)和nodeValue(节点值)三个基本属性
这些值是规定的:
- 元素节点 nodeType 值为 1
- 属性节点 nodeType 值为 2
- 文本节点nodeType 值为 3(文本节点包含文字、空格、换行等)
<!-- 节点的优点 -->
<div>我是div</div>
<span>我是span</span>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<div class="box">
<span class="erweima">×</span>
</div>
<script>
var box = document.querySelector('.box');
//打印这个元素对象
console.dir(box);
</script>
image.png
利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系
node.parentNode
它拿到的是离他最近的上一层,如果找不到父节点返回null
1.parentNode.childNodes(标准)
parentNode.childNodes返回包含指定节点的子节点的集合,该集合为即时更新的集合
注意:返回值里面包含了所有子节点,包括元素节点、文本节点等
如果只想获得里面的元素节点需要专门处理,所以一般不提倡使用childNodes,需要用循环取:
//如果要取到变迁中的元素,需要用下面的方法循环去取,所以,一般不提倡使用childNodes
var ul = document.querySelector('ul');
for (var i = 0; i < ul.childNodes; i++) {
if (ul.childNodes[i].nodeType == 1) {
//ul.childNodes[i]是元素节点
console.log(ul.childNodes[i]);
}
}
<!-- 节点的优点 -->
<div>我是div</div>
<span>我是span</span>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<div class="box">
<span class="erweima">×</span>
</div>
<!-- <script>
// var box = document.querySelector('.box');
// //打印这个元素对象
// console.dir(box);
//1.父节点node.parentNode
//从前的写法:
var erweima = document.querySelector('.erweima');
var box = document.querySelector('.box');
//现在如果想要拿到box,就按下面这样写:
//他拿到的是离他最近的,他的上一层,如果找不到父节点返回null
console.log(erweima.parentNode);;
</script> -->
<script>
//以前要拿ul里面的li要写两行,拿两次才行:
//利用DOM提供的方法(API)获取
var ul = document.querySelector('ul');
var lis = ul.querySelectorAll('li');
//子节点:parentNode.childNodes(标准)
console.log(ul.childNodes);
</script>
image.png之所以有9个节点,是因为ul标签到li标签之间是默认有一个换行的,这个换行是text属性,而且每一个li之间也有一个换行,就是每换一次行有一个text
console.log(ul.children);
image.png
子节点:
parentNode.firstChild
firstChild返回第一个子节点,找不到则返回null,同样,也是包含所有的节点,返回值带换行等节点
parentNode.lastChild
返回最后一个子节点,返回值带换行等节点
<ol>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
</ol>
<script>
//获取元素
var ol = document.querySelector('ol');
//parentNode.firstChild返回第一个子节点
//parentNode.firstChild返回最后一个子节点
//返回的还是9个节点,连换行都在其中.所以下面代码返回的都是text
console.log(ol.firstChild);
console.log(ol.lastChild);
image.png
有兼容性问题,IE9以上才支持
parentNode.firstElementChild
返回第一个子元素(不带换行等节点)
parentNode.lastElementChild
返回最后一个子元素(不带换行等节点)
实际开发中,firstChild和lastChild包含其他节点,操作不便,而firstElementChild和lastElementChild又有兼容问题,解决方案如下:
1.如果想要第一个元素节点,可以使用parentNode.children[0];
<ol>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
</ol>
<script>
//获取元素
var ol = document.querySelector('ol');
//parentNode.firstChild返回第一个子节点
//parentNode.firstChild返回最后一个子节点
//返回的还是9个节点,连换行都在其中.所以下面代码返回的都是text
console.log(ol.firstChild);
console.log(ol.lastChild);
//parentNode.firstElementChild返回第一个子元素,不代换行,比上面那两个好用
console.log(ol.firstElementChild);
console.log(ol.lastElementChild);
//实际开发中,既没有兼容问题,又返回第一个子元素:
console.log(ol.children[0]);
console.log(ol.children[3]);
</script>
image.png
分析:
1..nav ul { /* 先把弹出列表项隐藏起来 */ display: none; }
2.导航栏里面的li都要有鼠标经过的效果,所以要循环注册鼠标事件
3.原理:当鼠标经过li里面的第二个孩子ul显示,当鼠标离开,ul隐藏
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
a {
text-decoration: none;
font-size: 14px;
}
.nav {
margin: 100px;
}
.nav>li {
position: relative;
float: left;
width: 80px;
height: 41px;
text-align: center;
}
.nav li a {
display: block;
width: 100%;
height: 100%;
line-height: 41px;
color: #333;
}
.nav>li>a:hover {
background-color: #eee;
}
.nav ul {
/* 先把弹出列表项隐藏起来 */
display: none;
position: absolute;
top: 41px;
left: 0;
width: 100%;
border-left: 1px solid #FECC5B;
border-right: 1px solid #FECC5B;
}
.nav ul li {
border-bottom: 1px solid #FECC5B;
}
.nav ul li a:hover {
background-color: #FFF5DA;
}
</style>
</head>
<body>
<ul class="nav">
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
</ul>
<script>
//1.获取元素
var nav = document.querySelector('.nav');
//2.获取ul的四个小li
var lis = nav.children;
//3.循环注册事件
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function() {
//鼠标经过,让li里面的ul显示
//block:正常显示,none:不显示,隐藏
this.children[1].style.display = 'block';
}
lis[i].onmouseout = function() {
//鼠标离开,隐藏
this.children[1].style.display = 'none';
}
}
</script>
新浪下拉菜单.gif