1:DOM节点简介
根据 DOM规定,HTML 文档中的每个成分都是一个节点。
DOM 是这样规定的:
整个文档是一个文档节点。
每个 HTML 标签是一个元素节点。
包含在 HTML 元素中的文本是文本节点。
每一个 HTML 属性是一个属性节点。
注释属于注释节点。
2:如何获取DOM节点
(1)旧的获取节点引用方式。
getElementById()
getElementsByTagName()
getElementsByName()
缺点:浪费内存,逻辑性不强。
(2通过节点的关系属性来获得节点的引用。
对象.parentNode
获得父节点的引用。
<div id="parent">
<div id="center"></div>
</div>
<script>
var center = document.getElementById('center');
var parent = center.parentNode; //<div id="parent">....</div>
</script>
对象.childNodes
获得子节点的集合(子节点们),包括空白节点。IE7/8不包含空文本节点,但IE7包含首个注释节点(前面没有元素节点),IE8包含所有的注释节点。
<div id="parent">
<div id="up"></div>
<div id="center""></div>
<div id="down"></div>
</div>
<script>
var center = document.getElementById('center');
var parent = center.parentNode;
var children = parent.childNodes;
console.log(children); //NodeList(7) [text, div#up,text, div#center, text, div#down, text]
</script>
对象.children 获得子节点的集合,不包含空白节点。但IE7包含首个注释节点(前面没有元素节点),IE8包含所有的注释节点。
<div id="parent">
<div id="up"></div>
<div id="center""></div>
<div id="down"></div>
</div>
<script>
var center = document.getElementById('center');
var parent = center.parentNode;
var children = parent.children;
console.log(children); //HTMLCollection(3) [div#up, div#center, div#down,length:3]
</script>
对象.firstChild
获得第一个子节点。(IE7/8非空白节点,可能是注释节点)
<div id="parent">
<div id="up"></div>
<div id="center""></div>
<div id="down"></div>
</div>
<script>
var center = document.getElementById('center');
var parent = center.parentNode;
var firstChild = parent.firstChild;
console.log(firstChild); //#text
</script>
注:在IE下是第一个非空白元素节点
对象.firstElementChild
获得第一个非空白的子节点。(IE7/8不支持)
<div id="parent">
<div id="up"></div>
<div id="center""></div>
<div id="down"></div>
</div>
<script>
var center = document.getElementById('center');
var parent = center.parentNode;
var firstChild = parent.firstElementChild;
console.dir(firstChild); //div#up
</script>
注:在低版本ie下不支持,是undefined
兼容各个浏览器写法:
var firstChild = parent.firstElementChild || parent.firstChild;
对象.lastChild
获得最后一个子节点。(IE7最后一个元素节点,IE8最后一个非空白节点,可能是注释节点)
<div id="parent">
<div id="up"></div>
<div id="center""></div>
<div id="down"></div>
</div>
<script>
var center = document.getElementById('center');
var parent = center.parentNode;
var lastChild = parent.lastChild;
console.dir(lastChild); //#text
</script>
注:在IE下就是最后一个非空白元素节点
对象.lastElementChild
获得最后一个非空白的子节点。(IE7/8不支持)
<div id="parent">
<div id="up"></div>
<div id="center""></div>
<div id="down"></div>
</div>
<script>
var center = document.getElementById('center');
var parent = center.parentNode;
var lastChild = parent.lastElementChild;
console.dir(lasttChild); //div#down
</script>
注:在低版本ie下不支持,是undefined
兼容各个浏览器写法:
var lastChild = parent.lastElementChild || parent.lastChild;
对象.nextSibling
获得下个兄弟节点的引用。(包括空白节点和注释。IE7/8包括注释节点,不包括空白节点。)
var nextSibling = center.nextSibling;
console.dir(nextSibling ); //#text
对象.nextElementSibling
获得下个兄弟节点的引用。 (IE7/8不支持)
var nextSibling = center.nextElementSibling;
兼容写法:
var nextSibling = center.nextElementSibling || center.nextSibling;
对象.previousSibling
获得上个兄弟节点的引用。(包括空白节点和注释。 IE7/8包括注释节点,不包括空白节点。)
var previousSibling = center.previousSibling;
console.dir(nextSibling );
对象.previousElementSibling
获得上个兄弟节点的引用。(IE7/8不支持)
var prevSibling = center.previousElementSibling;
console.dir(prevSibling ); //div#up
兼容写法:
var prevSibling = center.previousElementSibling || center.previousSibling;
缺点:兼容性不好。
3:节点其它属性
ownerDocument:
获取该节点的文档根节点,相当于 document。
<div id="parent">
<div id="up"></div>
<div id="center""></div>
<div id="down"></div>
</div>
<script>
var center = document.getElementById('center');
console.log(center.ownerDocument); //#document
</script>
attributes:
获取当前元素节点的所有属性节点集合(IE7下不正常)。
<div id="parent">
<div id="up"></div>
<div id="center" class="aaa bbb ccc" age="18" title="这是标题"></div>
<div id="down"></div>
</div>
<script>
var center = document.getElementById('center');
console.log(center.attributes); //NamedNodeMap {0: id, 1: class, 2: age, 3: title, id: id, class:
class, age: age, title: title, length: 4}
</script>
tagName:
获取元素节点的标签名。
console.log(center.tagName); // DIV
id
:元素节点的ID名称。
console.log(center.id); //center
title:
元素节点的title属性值(鼠标悬停时提示)
console.log(center.title); //这是标题
className:
元素节点的类名(不可以使用class)
console.log(center.className); //aaa bbb ccc
4:节点信息(属性)
节点类型 节点名字 节点值
nodeType(数值) nodeName nodeValue
元素节点 1 标签名 null
属性节点 2 属性名 属性值
文本节点 3 #text 文本
注释节点 8 #comment 注释的文字
文档节点 9 #document null
Eg:
元素节点:
console.log(center.nodeName); //DIV
console.log(center.nodeType); // 1
console.log(center.nodeValue); //null
属于节点:
var attr = center.attributes[0];
console.log(attr.nodeName); // id
console.log(attr.nodeType); //2
console.log(attr.nodeValue); // center
文本节点:
var text = document.createTextNode('这是一段文本');
console.log(text.nodeType); //3
console.log(text.nodeName); //#text
console.log(text.nodeValue); //这是一段文本
注:
注释节点一样
// 扩展知识(添加class名)
// 判断class名(因为有的话在加会重复)
function hasClass(obj, className) {
var allClass = obj.className;
if(allClass.indexOf(className) !== -1) {
return true;
} else {
return false;
}
}
// 添加class名
function addClass(obj, className) {
if(!hasClass(obj, className)) {
obj.className = obj.className + ' ' + className;
}
}
addClass(center, 'ddd');
元素身上的一些属性:
center.classList.add('ccc');
center.classList.remove('ccc');
//查 看有没有
console.log(center.classList.contains('bbb')); center.classList.replace('bbb', 'ddd');
//toggle有就删除,没有就加
center.classList.toggle('eee'); center.classList.toggle('eee');
console.dir(center);
var oNewP = document.createElement('p');
oNewP.innerHTML = '你好!';
center.after(oNewP);
center.before(oNewP);
center.append(oNewP);
center.remove();
center.replaceWith(oNewP);
1:隔行变色。
<h2 id="title">新闻列表</h2>
<ul id="list">
<li>这是第1个LI</li>
<li>这是第2个LI</li>
<li>这是第3个LI</li>
<li>这是第4个LI</li>
<li>这是第5个LI</li>
<li>这是第6个LI</li>
</ul>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
#title {
padding: 10px 0;
text-align: center;
}
#list li{
padding: 0 4px;
line-height: 30px;
border-top: 1px dashed #ccc;
}
</style>
<script>
var list = document.getElementById('list');
var aLi = list.children;
for(var i = 0; i < aLi.length; i++) {
if(i % 2 === 0) {
aLi[i].style.background = '#eee';
}
aLi[i].onmouseover = function () {
this.style.background = 'skyblue';
};
aLi[i].index = i;
aLi[i].onmouseout = function () {
if(this.index % 2 === 0) {
this.style.background = '#eee';
} else {
this.style.background = '#fff';
}
};
}
</script>
2:进度条。
![](https://i-blog.csdnimg.cn/direct/3c95740643fc4906a59cc909a4f49849.png)
<div id="outer">
<div id="inner">0%</div>
</div>
<style>
* {
margin: 0;
padding: 0;
}
#outer {
margin: 50px auto;
width: 800px;
background: #eee;
}
#inner {
width: 0;
line-height: 30px;
text-align: center;
color: #fff;
background: blue;
}
</style>
<script>
var outer = document.getElementById('outer');
var inner = document.getElementById('inner');
var timer = setInterval(function () {
inner.style.width = inner.offsetWidth + 17 + 'px';
inner.innerHTML = Math.round( inner.offsetWidth / outer.offsetWidth * 100 ) + '%';
if(inner.offsetWidth >= outer.offsetWidth) {
clearInterval(timer);
inner.style.width = outer.offsetWidth + 'px';
inner.innerHTML = '100%';
}
}, 100);
</script>
5:创建文档碎片
语法:
var oFragment = document.createDocumentFragment();
![](https://i-blog.csdnimg.cn/direct/799e4a9f926f452b8c82f4fad7ff4e2a.png)
经过测试,在ie,firefox下性能明显得以提高。
比如创建10000个li:
<ul id="list"></ul>
<script>
var oList = document.getElementById('list');
for(var i = 0; i < 10000; i++) {
var oLi = document.createElement('li');
oLi.innerHTML = '这是第' + i + '个LI!';
oList.appendChild(oLi);
}
</script>
文档碎片方法:
var oFragement = document.createDocumentFragment();
for(var i = 0; i < 10000; i++) {
var oLi = document.createElement('li');
oLi.innerHTML = '这是第' + i + '个LI!';
oFragement.appendChild(oLi);
}
oList.appendChild(oFragement);
6:节点计算属性
1:offsetParent
:获取元素的最近的具有定位属性(absolute或者relative)的父级元素。如果都没有则返回body。(当position:static是没作用)
<div id="parent" style = “position: relative;”>
<div id="son">
<div id="outer">
<div id="inner"></div>
</div>
</div>
</div>
<script>
var outer = document.getElementById('outer');
console.log(outer.offsetParent); //<div id =‘parent>...</div>
</script>
2:offsetLeft:
获取元素相对具有定位属性的父级元素的左侧偏移距离。(子元素的marginLeft + left + 父元素的paddingLeft)
3:offsetTop:
获取元素相对就有定位属性的父级元素的顶部偏移距离。(子元素的marginTop + top + 父元素的paddingTop)
4:scrollLeft/scrollTop:
滚动条最顶端和窗口中可见内容的最顶端之间的距离。
6:clientWidth/clientHeight
:元素视窗宽度/高度。
5:offsetWidth/offsetHeight:
元素实际宽度/高度。
6:scrollWidth/scrollHeight:
获取对象的滚动宽度/高度。
<div id="a">
<div id="b">1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>
</div>
</div>
<style>
#a {
width: 100px;
height: 100px;
border: 1px solid #ccc;
overflow: auto;
}
#b {
height: 300px;
}
</style>
<script>
var a = document.getElementById('a');
a.onscroll = function () {
console.log(a.scrollTop);
console.log(a.clientWidth);
console.log(a.clientHeight);
console.log(a.offsetWidth);
console.log(a.offsetHeight);
console.log(a.scrollWidth);
console.log(a.scrollHeight);
};
</script>
7:获取FORM表单
一:通过直接定位的方式来获取
document.getElementById();
document.getElementsByName();
document.getElementsByTagName();
二:通过集合的方式来获取引用
<button id="submit-form">提交FORM表单</button>
<form name="login">
<div>账号:<input type="text" name="account" value="你好"></div>
<div>密码:<input type="password" name="password"></div>
<div>
性别:<input type="radio" name="sex" value="1">男<input type="radio" name="sex" value="0">女<input type="radio" name="sex" value="-1">保密
</div>
<div>爱好:<input type="checkbox" name="hobby" value="basketball">篮球<input type="checkbox" name="hobby" value="football">足球<input type="checkbox" name="hobby" value="pingpang">乒乓球<input type="checkbox" name="hobby" value="baseball">棒球<input type="checkbox" name="hobby" value="volleyball">排球</div>
<div>地区:<select name="area">
<option value="0">请选择</option>
<optgroup>
<option value="4">西安市</option>
<option value="7" selected>渭南市</option>
<option value="8">宝鸡市</option>
<option value="9">咸阳市</option>
</optgroup>
<optgroup>
<option value="4">西安市</option>
<option value="7" selected>渭南市</option>
<option value="8">宝鸡市</option>
<option value="9">咸阳市</option>
</optgroup>
</select></div>
<input type="submit" value="提交" name="btn">
</form>
1.通过下标的形式
document.forms[下标]
console.log( document.forms[0] ); //<form name="login">...</form>
2.通过name形式
document.forms["name"] document.forms.name
console.log( document.forms['login'] ); //<form name="login">...</form>
三:通过name直接获取(只适用于表单)
document.name
console.log(document.login); //<form name="login">...</form>
8:获取FORM表单元素
一:通过直接定位的方式来获取
document.getElementById();
document.getElementsByName();
document.getElementsByTagName();
二:通过集合来获取
表单对象.elements
// 获得表单里面所有元素的集合
表单对象.elements[下标]
var login = document.login;
console.log(login.elements[1]); //<input type="password" name="password">
表单对象.elements["name"]
var login = document.login;
console.log(login.elements['password']); //<input type="password" name="password">
表单对象.elements.name
三:直接通过name的形式
表单对象.name
// name指的是元素的name
var login = document.login;
console.log(login.account); //<input type="text" name="account" value="你好">
9:表单元素共同的属性和方法
一:获取表单元素的值
表单元素对象.value
// 获取或是设置值
var login = document.login;
console.log(document.login.account.value); //你好
document.login.account.value = '早上好';
console.log(document.login.account.value); //早上好
二:属性
disabled
// 获取或设置表单控件是否禁用 true false
var login = document.login;
console.log(document.login.password.disabled); //false
document.login.password.disabled = true;
console.log(document.login.password.disabled); //true
form
// 指向包含本元素的表单的引用。(通过表单中元素找到相应的表单)
var login = document.login;
console.log(document.login.password.form); ///<form name="login">...</form>
三:方法 表单元素是否获得焦点
blur()
// 失去焦点
focus()
// 获得焦点
var login = document.login;
document.login.password.focus();
document.login.password.blur();
10:操作FORM表单元素
document.login.btn.onclick = function () {
console.log(document.login.sex.value);
document.login.sex.value = '-1';
console.log(document.login.sex);
for(var i = 0; i < document.login.sex.length; i++) {
var oInput = document.login.sex[i];
console.log(oInput.checked);
}
console.log(document.login.hobby);
var hobbies = [];
for(var i = 0; i < document.login.hobby.length; i++) {
var hobby = document.login.hobby[i];
if(hobby.checked == true) {
hobbies.push(hobby.value);
}
}
console.log(hobbies);
console.log(document.login.area.value);
document.login.area.value = 4;
console.log(document.login.area.selectedIndex);
document.login.area.selectedIndex = 3;
var options = document.login.area.children;
for(var i = 0; i < options.length; i++) {
console.log(options[i].selected);
}
};
一:文本域
value属性:
设置或者获取值。
二:单选按钮
checked属性:
返回或者设置单选的选中状态。true 选中,false 未选中。
value属性:获取选中的值,必须先判断单选按钮是否被选中。
三:多选按钮
checked属性:
返回或者设置单选的选中状态。true 选中,false 未选中。
value属性:
获取选中的值,必须先判断选中状态。
四:下拉框
selected属性:
给option设置或返回下拉框的选中状态。true 选中,false 未选中。
selectedIndex属性:
设置或返回下拉框被选中的索引号。
五:文本区域
value属性:
设置或者获取值。
六:验证表单
1:事件
onsubmit 当表单提交的时候触发的事件。
document.login.onsubmit = function () {
console.log(1);
return false;
}
onblur 失去焦点。
onfocus 获得焦点
document.login.account.onfocus = function () {
this.value = '';
}
onchange 下拉框改变值的时候。
document.login.area.onchange = function () {
console.log(this.value);
}
2:return false; // 阻止事件的默认行为(适用于所有事件)。
七:提交方法
表单对象.submit();
document.getElementById('submit-form').onclick = function () {
document.login.submit();
};
应用:
2:简易年历。
<table id="calendar" border="1">
<tr>
<td>1月</td>
<td>2月</td>
<td>3月</td>
<td>4月</td>
</tr>
<tr>
<td>5月</td>
<td>6月</td>
<td>7月</td>
<td>8月</td>
</tr>
<tr>
<td>9月</td>
<td>10月</td>
<td>11月</td>
<td>12月</td>
</tr>
</table>
<div id="show"></div>
<style>
* {
margin: 0;
padding: 0;
}
#calendar {
margin: 50px auto 0;
width: 600px;
border-collapse: collapse;
border-color: pink;
line-height: 40px;
text-align: center;
}
#show {
margin: 0 auto;
width: 600px;
padding: 40px 0;
border: 1px solid #ccc;
border-top: none;
text-align: center;
}
.active {
color: #fff;
background: skyblue;
}
</style>
<script>
var poetry = [
'爆竹声中一岁除,春风送暖入屠苏!',
'不知细叶谁裁出,二月春风似剪刀!',
'故人西辞黄鹤楼,烟花三月下扬州!',
'人间四月芳菲尽,山寺桃花始盛开!',
'五月天山雪,无花只有寒!',
'毕竟西湖六月中,风光不与四时同!',
'七月七日长生殿,夜半无人私语时!',
'八月秋高风怒号,卷我屋上三重茅!',
'可怜九月初三夜,露似真珠月似弓!',
'庭中栽得红荆树,十月花开不待春!',
'夜阑卧听风吹雨,铁马冰河入梦来!',
'忽如一夜春风来,千树万树梨花开!'
];
var show = document.getElementById('show');
var tds = document.getElementsByTagName('td');
// 页面初始化
var date = new Date();
var month = date.getMonth();
show.innerHTML = poetry[month];
// 初始化class
tds[month].className = 'active';
for(var i = 0; i < tds.length; i++) {
tds[i].index = i;
tds[i].onclick = function () {
show.innerHTML = poetry[this.index];
// 重置class
for(var j = 0; j < tds.length; j++) {
tds[j].className = '';
}
this.className = 'active';
}
}
</script>
3:自动登录勾选。
![](https://i-blog.csdnimg.cn/direct/f950743610b1412b949b5b88afc3f8dd.png)
综合应用:
1:点击按钮换图片。
2:tab切换案例。
扩展案例
:QQ延迟提示框。
周六作业:
1:苹果菜单。
2:扩展案例:密码强度。
![](https://i-blog.csdnimg.cn/direct/673e50ea3d66429f86a67534de40496d.png)