- DOM,全称Document Object Model文档对象模型
- 文档:表示整个的HTML网页文档
- 对象:表示将网页中的每一个部分都转换为了一个对象
- 模型:使用模型来表示对象之间的关系
- 节点Node:是构成网页的最基本的组成部分,网页中的每一个部分都可以称为是一个节点
- 文档节点:整个HTML文档
- 元素节点:HTML文档中的标签
- 属性节点:元素的属性
- 文本节点:标签中的文本内容
节点的属性
nodeName | nodeType | nodeValue | |
---|---|---|---|
文档节点 | #document | 9 | null |
元素节点 | 标签名 | 1 | null |
属性节点 | 属性名 | 2 | 属性值 |
文本节点 | #text | 3 | 文本内容 |
<button id="btn">我是一个按钮</button>
<script type="text/javascript">
// 浏览器已经提供文档节点对象document
// 这个对象是window对象的属性,可以在页面中直接使用
var btn = document.getElementById("btn");
console.log(btn.innerHTML);
btn.innerHTML = 'I am a Button';
</script>
事件就是用户和浏览器之间的交互行为,比如:点击按钮,移动鼠标,关闭窗口等
<!--
可以在事件对应的属性中设置一些js代码,这样当事件被触发时,这些代码将会执行
这种写法将结构与行为耦合,不方便维护,不推荐使用
-->
<button id="btn" onclick="alert('讨厌~你点我干嘛')">我是一个按钮</button>
<!--
可以为按钮的对应事件绑定处理函数的形式来响应事件
这样当事件被触发时,其对应的函数将会被调用
-->
<button id="btn">我是一个按钮</button>
<script type="text/javascript">
var btn = document.getElementById("btn");
// 绑定一个单击事件
btn.onclick = function () {
alert("别点了~");
};
</script>
页面的加载
- 浏览器在加载一个页面时,是按照自上向下的顺序加载的,读取到一行就运行一行
- 如果将script标签写到页面的上边,在代码执行时,页面还没有加载,此时无法获取到DOM对象
- 将js代码编写到页面的下部就是为了可以在页面加载完毕以后再执行js代码
<button id="btn">我是一个按钮</button>
/*
onload事件会在整个页面加载完成之后才触发
为window绑定一个onload事件,该事件对应的响应函数将会在页面加载完成之后执行
这样可以确保代码执行时页面已经加载完毕
*/
window.onload = function () {
var btn = document.getElementById("btn");
// 绑定一个单击事件
btn.onclick = function () {
alert("别点了~");
};
};
DOM查询
1. 获取元素节点(通过document对象调用)
<div>
<p>你喜欢哪个城市?</p>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
</div>
<div>
gender:
<input class="hello" type="radio" name="gender" value="male" />Male
<input class="hello" type="radio" name="gender" value="female" />Female
<br>
<br>
name:
<input type="text" name="name" id="username" value="abcde" />
</div>
通过id属性获取一个元素节点对象
window.onload = function () {
// 获取id为bj的节点
var r1 = document.getElementById("bj");
console.log(r1.innerHTML); // 北京
}
通过标签名获取一组元素节点对象
window.onload = function () {
// 获取所有li节点
var r2 = document.getElementsByTagName("li");
for (let i = 0; i < r2.length; i++) {
console.log(r2[i].innerHTML); // 北京 上海 东京 首尔
}
}
通过name属性获取一组元素节点对象
window.onload = function () {
// 获取name=gender的所有节点
var r3 = document.getElementsByName("gender");
for (let i = 0; i < r3.length; i++) {
// innerHTML 对自结束标签不生效
// 直接使用对象读取属性的方式就可以获取到节点的属性值
console.log(r3[i].value); // male female
// class属性不能采用这种方式
console.log(r3[i].className); // hello hello
}
}
2. 获取元素节点的子节点(通过具体的元素节点调用)
<div>
<p>你喜欢哪个城市?</p>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<p>你喜欢哪个人物?</p>
<ul>
<li>费渡</li>
<li>盛望</li>
<li>沈兰舟</li>
</ul>
</div>
获取当前节点的指定标签名后代节点
window.onload = function () {
var city = document.getElementById("city");
var liList = city.getElementsByTagName("li");
for (let i = 0; i < liList.length; i++) {
console.log(liList[i].innerHTML); // 北京 上海 东京 首尔
}
};
当前节点的所有子节点
window.onload = function () {
var city = document.getElementById("city");
var childNodes = city.childNodes;
// childNodes属性会获取包括文本节点在内的所有节点
// 此时DOM标签之间的空白也会被当成文本节点(IE8及以下没有这种行为)
console.log(childNodes.length);// 9
// children属性可以获取当前元素的所有子元素
var children = city.children;
console.log(children.length); // 4
};
当前节点的第一个子节点(最后一个子节点用 last)
window.onload = function () {
var city = document.getElementById("city");
// firstChild属性获取到当前元素的第一个子节点(包括空白文本)
var fChild = city.firstChild;
console.log(fChild);// #text
// firstElementChild属性获取当前元素的第一个子元素(IE8不支持)
var firstElementChild = city.firstElementChild;
console.log(firstElementChild.innerHTML);// 北京
};
3. 获取父节点和兄弟节点(通过具体的节点调用)
<div>
<p>你喜欢哪个城市?</p>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<p>你喜欢哪个人物?</p>
<ul>
<li>费渡</li>
<li id="sw">盛望</li>
<li>沈兰舟</li>
</ul>
</div>
获取当前节点的父节点
window.onload = function () {
var bj = document.getElementById("bj");
var ul = bj.parentNode;
console.log(ul.innerHTML);
// innerText会自动去除标签
console.log(ul.innerText);// 北京 上海 东京 首尔
};
获取当前节点的前一个兄弟节点(后一个用next)
window.onload = function () {
var sw = document.getElementById("sw");
// 也可能获取到空白文本
var prev = sw.previousSibling;
console.log(prev);// #text
// 不考虑文本(IE8及以下不支持)
var prevElement = sw.previousElementSibling;
console.log(prevElement.innerHTML);// 费渡
}
获取文本节点的内容可以使用nodeValue属性
window.onload = function () {
console.log(document.getElementById("bj").firstChild.nodeValue);// 北京
};
4. 其他查询方法
获取 body 标签
window.onload = function () {
var element = document.body;
console.log(element);
};
获取 html 根标签
window.onload = function () {
var element = document.documentElement;
console.log(element);
};
获取页面中的所有元素
window.onload = function () {
var element = document.all;
console.log(element);
element = document.getElementsByTagName("*");
console.log(element);
};
根据元素的class属性值查询一组元素节点对象
<div class="box1"></div>
<div class="box1"></div>
<div class="box1"></div>
window.onload = function () {
var element = document.getElementsByClassName("box1");
console.log(element.length);// 3 (IE9及以上支持)
};
根据CSS选择器来查询元素节点对象
<div class="box1">
<div>目标元素1</div>
<div>目标元素2</div>
<div>目标元素3</div>
</div>
window.onload = function () {
// 一个元素节点对象,返回查询到的第一个
var element = document.querySelector(".box1 div");
console.log(element.innerHTML);// 目标元素1
// 一组元素节点对象
element = document.querySelectorAll(".box1 div");
console.log(element.length);// 3
console.log(element[2].innerHTML);// 目标元素3
};
DOM增删改
<div id="total">
<div class="inner">
<p>你喜欢哪个城市?</p>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
</div>
</div>
创建与添加子节点
// 向id为city的元素中添加一个子元素“广州”
window.onload = function () {
// 创建元素节点对象,参数是标签名字符串
var li = document.createElement("li");
// 创建文本节点对象,参数是文本内容
var gz = document.createTextNode("广州");
// 向父节点中添加子节点
li.appendChild(gz);
var city = document.getElementById("city");
city.appendChild(li);
};
在指定节点前添加新的节点
// 向id为bj的元素前添加一个子元素“广州”
window.onload = function () {
var li = document.createElement("li");
var gz = document.createTextNode("广州");
li.appendChild(gz);
// 在指定的节点前添加新的节点,二者属于一个父节点,方法由父节点调用
// 第一个参数是要添加的新节点,第二个参数是指定的节点
var city = document.getElementById("city");
var bj = document.getElementById("bj");
city.insertBefore(li, bj);
};
用新节点替换指定的节点
// 用“广州”代替id为bj的节点
window.onload = function () {
var li = document.createElement("li");
var gz = document.createTextNode("广州");
li.appendChild(gz);
// 用新的节点替换指定的节点,二者属于一个父节点,方法由父节点调用
// 第一个参数是新节点,第二个参数是指定的节点
var city = document.getElementById("city");
var bj = document.getElementById("bj");
city.replaceChild(li, bj);
};
删除指定的节点
// 删除id为bj的节点
window.onload = function () {
// 删除指定的节点,方法由父节点调用
var city = document.getElementById("city");
var bj = document.getElementById("bj");
// city.removeChild(bj);
bj.parentNode.removeChild(bj);
};
使用DOM操作CSS样式
1. 读取和设置内联样式
<button id="btn01">按钮</button>
<br><br>
<div id="box1"></div>
#box1 {
width: 200px;
height: 200px;
background-color: red;
}
window.onload = function () {
var btn01 = document.getElementById("btn01");
btn01.onclick = function () {
var box1 = document.getElementById("box1");
/*
通过style属性设置和读取的样式都是内联样式,内联样式优先级较高,往往会立即显示
但是如果在样式表中使用了 !important,此时样式会有最高的优先级,使用JS也无法覆盖
*/
// 修改box1的样式
box1.style.width = "300px";
box1.style.height = "300px";
// 带连字符的属性要改成驼峰命名法
box1.style.backgroundColor = "yellow";
// 读取元素的样式值(读的也是内联样式)
alert(box1.style.backgroundColor); // yellow
};
};
2. 读取当前正在生效的样式
window.onload = function () {
var btn01 = document.getElementById("btn01");
btn01.onclick = function () {
var box1 = document.getElementById("box1");
/*
读取box1当前正在生效的样式
如果当前元素没有设置该样式,则返回该样式的默认值
只有IE支持
*/
// 此时获取到的样式都是只读的
alert(box1.currentStyle.width);// 200px
/*
第一个参数是要获取样式的元素,第二个可以传递一个伪元素
如果获取的样式没有设置,则返回该样式真实的值
IE8及以下不支持
*/
var obj = getComputedStyle(box1, null);
alert(obj.width);// 200px
// 兼容浏览器的获取样式的方式
alert(getStyle(box1, "width"));// 200px
};
// 第一个参数:要获取样式的元素
// 第二个参数:要获取的样式名
function getStyle(obj, name) {
if (window.getComputedStyle) {
return getComputedStyle(obj, null)[name];
} else {
return obj.currentStyle[name];
}
}
};
3. 其他样式相关的属性
属性都是只读的,不可以修改
<button id="btn01">按钮</button>
<br><br>
<div id="box4">
<div id="box5"></div>
</div>
<br><br>
<div id="box2" style="position: relative;">
<div id="box1"></div>
</div>
#box1 {
width: 200px;
height: 200px;
background-color: red;
padding: 10px;
border: 10px solid rosybrown;
}
#box2 {
background-color: yellow;
padding: 100px 150px;
}
#box4 {
width: 300px;
height: 300px;
background-color: turquoise;
overflow: scroll;
}
#box5 {
width: 450px;
height: 600px;
background-color: tomato;
}
获取元素的(内容区+内边距)的高度和宽度
window.onload = function () {
var box1 = document.getElementById("box1");
var btn01 = document.getElementById("btn01");
btn01.onclick = function () {
alert(box1.clientWidth);// 220
alert(box1.clientHeight);// 220
};
};
offset
window.onload = function () {
var box1 = document.getElementById("box1");
var btn01 = document.getElementById("btn01");
btn01.onclick = function () {
// 获取元素整个的高度和宽度(内容区+内边距+边框)
alert(box1.offsetWidth);// 240
alert(box1.offsetHeight);// 240
/*
前提:清掉html与body之间的margin
本身定位不为fixed
父级没有定位 ===> body
父级有定位 ===> 定位父级
本身定位为fixed
IE7以上(不是火狐) ===> null
火狐 ===> body
*/
alert(box1.offsetParent.id);// box2
// 获取当前元素相对其定位父元素的偏移量
alert(box1.offsetTop);// 100
alert(box1.offsetLeft);// 150
};
};
scroll
window.onload = function () {
var box1 = document.getElementById("box1");
var box4 = document.getElementById("box4");
var btn01 = document.getElementById("btn01");
btn01.onclick = function () {
// 获取元素整个滚动区域的宽度和高度
alert(box4.scrollHeight);// 600
alert(box4.scrollWidth);// 450
// 滚动条滚动的距离
alert(box4.scrollLeft);
alert(box4.scrollTop);
// scrollHeight - scrollTop = clientHeight 此时滚动条滚动到了底部
// scrollWidth - scrollLeft = clientWidth 此时滚动条滚动到了最右侧
};
};