**MDN 文档对象模型手册:**https://developer.mozilla.org/zh-CN/docs/Web/API/Document_Object_Model
DOM 英文全称“Document Object Model”,译为文档对象模型。
DOM 是一个与平台和编程语言无关的接口,通过这个接口程序和脚本可以动态的访问和修改文档的内容、结构和样式。
DOM最大的特点就是将文档表示为节点树
一、节点
1. 五大节点类型
类型 | 含义 | Nodetype |
---|---|---|
document | 文档类型节点 | 9 |
element | 元素类型节点 | 1 |
attribute | 属性类型节点 | 2 |
text | 文本类型节点 | 3 |
comment | 注释类型节点 | 8 |
2. 节点的属性
属性 | 含义 |
---|---|
nodeName | 节点名称 |
nodeValue | 节点值 |
nodeType | 节点类型 |
二、获取元素
1. 通过 ID 名getElementById
documet.getElementById('ID名')
- 如果有多个同ID名得元素,只获取第一个
- 如果找不到指定ID名得元素,返回null
2. 通过标签名getElementByTagName
从文档中获取:
document.getElementByTagName('标签名');
从某个元素的后代中获取:
元素对象.getElementByTagName('标签名');
- getElementByTagName()方法返回一个HTMLCollection对象,该对象是类数组
- 如果找不到符合条件的元素,返回空的元素,还是HTMLCollection对象
3. 通过类名(IE8 + 支持)getElementsByClassName
从文档中获取:
document.getElementsByClassName('item');
从元素的后代中获取:
元素对象.getElementsByClassName('item')
- getElementsByClassName() 方法返回一个 HTMLCollection 对象,该对象是类数组
- 如果找不到符合条件的元素,返回空的集合,还是 HTMLCollection 对象
4. 通过 name 属性值 getElementsByName
从文档中获取:
document.getElementsByName('name属性值');
无法从某个元素的后代中获取; 元素对象没有 getElementsByName() 方法
- getElementsByName() 方法返回一个 NodeList 对象,该对象是类数组
- 如果找不到符合条件的元素,返回空的集合,还是 NodeList 对象
5. 使用选择器获取元素 (推荐)
从文档中获取:
document.querySelector('选择器');
document.querySelectorAll('选择器');
从元素的后代中获取:
元素对象.querySelector('选择器');
元素对象.querySelectorAll('选择器');
- querySelector() 返回第一个符合条件的元素,如果没有符合条件的元素返回 null
- querySelectorAll() 返回由符合条件的元素组成的集合,是 NodeList 对象,是伪数组。
6. 获取文档中所有的元素
返回文档中所有的元素组成的集合,是伪数组
document.all
使用 document.all 可以快速判断 IE 还是 非IE:
// 快速判断IE还是非IE
if (document.all) {
document.write('是IE浏览器!');
} else {
document.write('不是IE浏览器!');
}
三、文档结构(根据元素关系获取元素)
1. 节点树
属性 | 含义 |
---|---|
parentNode | 获取父节点 |
childNodes | 获取所有子节点组成的集合,NodeList类型的对象 |
firstChild | 获取第一个子节点 |
lastChild | 获取最后一个子节点 |
previousSibling | 获取上一个兄弟节点 |
nextSibling | 获取下一个兄弟节点 |
2. 元素树
属性 | 含义 |
---|---|
parentElement | 获取父元素 |
children | 获取所有子节点组成的集合,HTMLCollection类型的对象 |
firstElementChild | 获取第一个子元素 |
lastElementChild | 获取最后一个子元素 |
previousElementSibling | 上一个兄弟元素 |
nextElementSibling | 下一个兄弟元素 |
四、元素的属性操作
1. 读写内置属性
内置元素指的是HTML标准版规范中规定好的属性,当获取到JS元素对象的时候,HTML标签的内置属性会变为JS对象的属性
元素对象.属性名;
// 设置
元素对象.属性名 = 值;
<img src="./src/assets/006WJqK7ly1hfvg3blrkhj30u00u07f2.jpg" alt="hello" width="400" title="wake up" id="myImg">
<script>
var imgEle = document.querySelector('#myImg')
console.log('src:', imgEle.src);
console.log('alt:', imgEle.alt);
console.log('title:', imgEle.title);
imgEle.onclick = function () {
imgEle.width = 200
}
</script>
2. 读写设置在标签代码上的属性
//读取
元素对象.getAttribute('属性名');
//设置
元素对象.setAttribute('属性名','值');
和内置属性不同的地方:
- 自定义的属性可以获取
- 不会处理,是什么就输出什么,相对路径不会处理成相对路径
- 所有属性值都是字符串
<img src="./src/assets/006WJqK7ly1hfvg3blrkhj30u00u07f2.jpg" alt="hello" width="400" title="wake up" id="myImg" random="random">
<script>
var imgEle = document.querySelector('#myImg')
console.log(imgEle.getAttribute('random'));
console.log(imgEle.getAttribute('alt'));
console.log(imgEle.getAttribute('src'));
imgEle.onclick = function () {
imgEle.setAttribute('width', '600')
}
</script>
3. data-*
形式的自定义属性
用在自定义属性上
<元素 data-home-address='值'>
元素对象.dataset.homeAddress;
元素对象.dataset.homeAddress = '值';
<img src="./src/assets/006WJqK7ly1hfvg3blrkhj30u00u07f2.jpg" alt="hello" width="400" title="wake up" id="myImg" data-random="random" data-load-pic="100.jpg">
<script>
var imgEle = document.querySelector('#myImg')
console.log(imgEle.getAttribute('data-random')); //random
console.log(imgEle.getAttribute('data-load-pic')); //100.jpg
console.log(imgEle.dataset.random);
console.log(imgEle.dataset.loadPic);
imgEle.onclick = function () {
imgEle.dataset.random = 'xx'
imgEle.dataset.homeAddressId = 200
}
</script>
4. 全选和取消全选案例
<ul id="selectBox">
<li>
<input type="checkbox">
Document Object Model
</li>
<li>
<input type="checkbox">
Document Object Model
</li>
<li>
<input type="checkbox">
Document Object Model
</li>
<li>
<input type="checkbox">
Document Object Model
</li>
</ul>
<hr>
<button id="btn1">全选</button>
<button id="btn2">取消全选</button>
<button id="btn3">反选</button>
<script>
var checkboxItems = document.querySelectorAll('#selectBox input')
var btn1 = document.querySelector('#btn1')
var btn2 = document.querySelector('#btn2')
var btn3 = document.querySelector('#btn3')
btn1.onclick = function () {
checkboxItems.forEach((i) => {
i.checked = true
})
}
btn2.onclick = function () {
for (var i = 0; i < checkboxItems.length; i++) {
checkboxItems[i].checked = false
}
}
btn3.onclick = function () {
checkboxItems.forEach((i) => {
// if (i.checked) {
// i.checked = false
// } else {
// i.checked = true
// }
i.checked = !i.checked
})
}
</script>
五、元素的样式操作
1. 读写行内样式
元素对象.style.CSS属性名;
元素对象.style.CSS属性名 = '新值';
如果属性名中有-,使用小驼峰或者中括号,如元素对象.style.backgroundColor
或元素对象.style['background-color']
该方式只能读取设置在行内的样式,使用该方式设置样式会设置在行内。
<button id="btn01">get</button>
<div id="box" style="width: 400px;height: 400px;background-color: azure;"></div>
<script>
var box = document.querySelector('#box')
var btn01 = document.querySelector('#btn01')
btn01.onclick = function () {
box.style.backgroundColor = '#ccc'
}
</script>
2. 读取计算样式
计算样式:最终作用在元素上的样式,即使没有设置过也有默认样式。只能读取不可以设置
getComputedStyle(元素对象).属性名;
getComputedStyle(元素对象)['属性名'];
getComputedStyle(元素对象); //该方法返回是个对象
<button id="btn01">get</button>
<div id="box" style="width: 400px;height: 400px;background-color: azure;"></div>
<script>
var box = document.querySelector('#box')
var btn01 = document.querySelector('#btn01')
var styleObj = getComputedStyle(box)
btn01.onclick = function () {
console.log(styleObj.width);
console.log(styleObj['background-color']);
}
</script>
兼容性写法(了解)
// 封装读取计算样式的函数
function getStyle(ele, attrName) {
// 判断是否支持 getComputedStyle
if (window.getComputedStyle) {
return getComputedStyle(ele)[attrName];
} else if (ele.currentStyle) {
// IE的用法
return ele.currentStyle[attrName];
} else {
return false;
}
}
3. 通过设置元素的类名操作样式
-
className
元素对象.className; // 可读可写
class 在 JS中是保留字, JS 的元素对象使用 className 属性对应 html 标签上的 class 属性
-
classList
元素对象.classList; //获取到由元素的类名组成的集合,是个伪数组对象
方法 含义 contains() 判断是否包含一个类名 add() 添加一个类名 remove() 删除一个类名 toggle() 切换一个类名(原来有该类型就移除,原来没有该类名就添加)
var itembox = document.querySelectorAll('.item')
itembox.forEach(function (i) {
i.onclick = function () {
// 使用className
// if (i.className == 'item active') {
// i.className = 'item'
// } else {
// i.className = 'item active'
// }
// 使用classList
// console.log(i.classList);
// if (i.classList.contains('active')) {
// i.classList.remove('active')
// } else {
// i.classList.add('active')
// }
// 最简便方法
i.classList.toggle('active')
}
})
六、元素的文本内容(可读可写)
属性 | 含义 |
---|---|
innerHTML | 读写元素中html代码和文本 |
outerHTML | 读写元素中html代码和文本(包括元素自己的标签代码) |
innerText | 读写元素中的文本内容(html标签会被剔除)(保留文本中的多的空格) |
textContent | 读写元素中的文本内容(html标签会被剔除)(保留文本中的空格) |
七、元素的尺寸(只读)
属性 | 含义 |
---|---|
offsetWidth/offsetHeight | 读取元素的总宽度和总高度 |
clientWidth/clientHeight | 读取内容+内边距的宽高 |
scrollWidth/scrollHeight | 在client的基础上加上溢出部分的宽高 |
元素对象.getBoundingClientRect().width //同offsetWidth
元素对象.getBoundingClientRect().height //同offsetHeight
读取视口的尺寸:
视口宽度:document.documentElement.clientWidth
视口高度:document.documentElement.clientHeight
相对于widow.innerWidth、window.innerHeight,本方案不会将滚动条本身的宽度算进去
// 读取视口的宽高
console.log(window.innerWidth); //691
console.log(window.innerHeight); //883
console.log(document.documentElement.clientWidth); //674
console.log(document.documentElement.clientHeight); //883
八、元素的位置 (只读)
属性 | 含义 |
---|---|
offsetLeft / offsetTop | 读取在第一个定位的祖先元素上的位置,如果没有定位的祖先元素,在整个页面 |
clientLeft / clientTop | 读取左边框宽度/上边框宽度 |
getBoundingClientRect()
返回一个对象,对象中有如下属性:
属性 | 含义 |
---|---|
left | 在视口上的位置 x坐标 |
top | 在视口上的位置 y坐标 |
x | 同 left |
y | 同 top |
right | 元素的右下角在视口上的x坐标 |
bottom | 元素的右下角在视口上的y坐标 |
九、元素中内容的位置(可读可写)
属性 | 含义 |
---|---|
scrollLeft | 元素中的内容在元素上的水平位置, 值越大,内容越向左滚动(滚动条越向右) |
scrollTop | 元素中的内容在元素上的竖直位置, 值越大,内容越向上滚动(滚动条越向下) |
注意: 被操作的元素,
overflow
的属性值不能是 visible。
读写页面在视口上的位置(滚动的距离)
// 非IE的用法
document.documentElement.scrollTop;
document.documentElement.scrollLeft;
// IE 的用法
document.body.scrollTop;
document.body.scrollLeft;
// 兼容性写法
document.documentElement.scrollTop || document.body.scrollTop;
十、节点的添加/删除/替换/克隆
方法 | 含义 |
---|---|
creatElement(‘标签名’) | 创建元素节点 |
appendChild(新节点) | 添加子节点,新节点作为父元素的最后一个子节点 |
insertBefore(新节点, 旧节点) | 添加子节点,新节点会添加到旧节点的前面 |
removeChild(要删除的节点) | 删除子节点 |
replaceChild(新节点, 旧节点) | 替换子节点 |
cloneNode() | 返回复制好的元素 参数默认false,表示只克隆元素本身不克隆里面的内容 如果设置为true,连同里面的内容后代元素一起克隆 |
<div class="todolist">
<div class="todo-header">
<input type="text" id="input">
<button id="addBtn">添加</button>
<button id="insertBtn">插入</button>
<button id="deleteBtn">删除</button>
<button id="replaceBtn">替换</button>
<button id="cloneBtn">克隆</button>
</div>
<div class="todo-body">
<ul id="todoContent">
<li>苹果</li>
<li>西瓜</li>
</ul>
</div>
</div>
<li id="freeLi">草莓</li>
<script>
// 获取相关元素
var todoContent = document.querySelector('#todoContent');
var inputEle = document.querySelector('#input');
var addBtn = document.querySelector('#addBtn');
var insertBtn = document.querySelector('#insertBtn');
var deleteBtn = document.querySelector('#deleteBtn');
var repalceBtn = document.querySelector('#replaceBtn');
var cloneBtn = document.querySelector('#cloneBtn');
var freeLi = document.querySelector('#freeLi');
// 给每个 li 监听单击事件
[].forEach.call(todoContent.children, function (liItem) {
liItem.onclick = function () {
liItem.classList.toggle('active');
}
});
// 点击添加按钮
addBtn.onclick = function () {
// 创建新元素
var newLi = document.createElement('li');
// 设置li中的文本内容
newLi.innerHTML = inputEle.value;
// 将 li 添加到 ul 的里面
todoContent.appendChild(newLi);
};
// 点击插入按钮 实现代办事项插入到最前面
insertBtn.onclick = function () {
// 创建新元素
var newLi = document.createElement('li');
// 设置li中的文本内容
newLi.innerHTML = inputEle.value;
// 给ul添加子元素 指定位置
todoContent.insertBefore(newLi, todoContent.firstChild);
};
// 点击删除按钮,删除选中的元素
deleteBtn.onclick = function () {
// 获取到被选中的元素
var selectedLis = document.querySelectorAll('#todoContent li.active');
// 遍历被选中的元素,挨个删除
selectedLis.forEach(function (selectedLi) {
todoContent.removeChild(selectedLi);
});
};
// 点击替换
repalceBtn.onclick = function () {
// 创建新元素
var newLi = document.createElement('li');
// 设置li中的文本内容
newLi.innerHTML = inputEle.value;
// 获取到被选中的元素
var selectedLis = document.querySelectorAll('#todoContent li.active');
// 遍历被选中的元素,挨个替换
selectedLis.forEach(function (selectedLi) {
todoContent.replaceChild(newLi.cloneNode(true), selectedLi);
});
};
// 点击克隆
cloneBtn.onclick = function () {
todoContent.appendChild(freeLi.cloneNode(true))
}
</script>
十一、HTML DOM
1. 表单相关元素
1.1 form 元素
方法 | 含义 |
---|---|
submit() | 调用时,表单会提交 |
reset() | 调用时,表单会重置 |
<form action="http://www.baidu.com/s" id="myForm">
<input type="text" name="wd">
</form>
<hr>
<button id="btn">搜索</button>
<script>
// 获取form元素
var formBox = document.querySelector('#myForm');
// 获取按钮 双击按钮 提交表单
var btn = document.querySelector('#btn');
btn.ondblclick = function() {
formBox.submit();
};
// 10s 之后表单自动重置
setTimeout(function() {
formBox.reset();
}, 10000);
</script>
1.2 文本输入框和文本域(input 和 textarea)
方法 | 含义 |
---|---|
focus() | 获取焦点 |
blur() | 失去焦点 |
select() | 选中里面的内容 |
<button id="btn1">获取焦点</button>
<button id="btn2">失去焦点</button>
<button id="btn3">选中内容</button>
<hr>
<input type="text" id="input">
<br>
<textarea name="" id="txt" cols="30" rows="10"></textarea>
<script>
// 获取input和textarea
var input = document.querySelector('#input');
var textarea = document.querySelector('#txt');
var btn1 = document.querySelector('#btn1');
var btn2 = document.querySelector('#btn2');
var btn3 = document.querySelector('#btn3');
// 点击获取焦点
btn1.onclick = function() {
textarea.focus();
input.focus();
}
// 点击失去焦点
btn2.onclick = function(){
input.blur();
}
// 点击选中内容
btn3.onclick = function() {
textarea.select();
input.select();
}
</script>
1.3 select 元素
属性和方法 | 含义 |
---|---|
value | 获取被选中选项的value |
selectedIndex | 获取被选中选项的索引 |
options | 获取所有选项的集合 |
add() | 添加一个选项,参数时option元素 |
remove() | 删除一个选项,参数是要删除选项的索引 |
特殊的地方,option和img可以new来创建元素
new Option('选项内容','value值');
<button id="btn1">获取选中的选项</button>
<button id="btn2">删除选中的选项</button>
<hr>
<select id="addressBox"></select>
<script>
// 创建数组 定义地址信息
var addressData = ['江苏', '江西', '浙江', '安徽', '河南', '新疆维吾尔自治区'];
// 获取 select元素
var selectBox = document.querySelector('#addressBox');
// 遍历数组
addressData.forEach(function(item, index) {
// 创建option元素 并添加到 select 中
selectBox.add(new Option(item, index));
});
// 点击按钮 获取选中的选项
var btn1 = document.querySelector('#btn1');
btn1.onclick = function() {
console.log('所选选项的value:', selectBox.value);
console.log('所选选项的索引:', selectBox.selectedIndex);
// 选中的 options 元素
console.log(selectBox.children[selectBox.selectedIndex]);
console.log(selectBox.options[selectBox.selectedIndex]);
};
// 点击按钮 删除选中的选项
var btn2 = document.querySelector('#btn2');
btn2.onclick = function() {
// selectBox.removeChild(selectBox.options[selectBox.selectedIndex]);
selectBox.remove(selectBox.selectedIndex);
}
</script>
2. 表格相关元素
2.1 table 元素
方法 | 含义 |
---|---|
insertRow() | 创建并添加tr元素 |
deleteRow() | 删除一行,参数是行的索引 |
2.2 tableRow 元素(tr 元素)
属性和方法 | 含义 |
---|---|
cells | 获取本行所有单元格组成的集合 |
rowIndex | 读取该行的索引 |
insertCell() | 创建并添加td元素 |
deleteCell() | 删除一个单元格,参数是单元格的索引 |
2.3 tableCell 元素 (td 或 th)
属性 | 含义 |
---|---|
cellIndex | 读取该单元格在行的索引 |
// 获取元素
var tableBox = document.querySelector('#table');
var nameInput = document.querySelector('#name');
var addressInput = document.querySelector('#address');
var phoneInput = document.querySelector('#phone');
var btn = document.querySelector('#btn');
// 获取到所有的删除按钮
var deleteBtns = document.querySelectorAll('.delete-btn');
// 点击按钮 给表格添加一行
btn.onclick = function() {
// 创建并添加 tr 元素
var tr = tableBox.insertRow();
// 在 tr 中添加 td
tr.insertCell().innerHTML = '';
tr.insertCell().innerHTML = nameInput.value;
tr.insertCell().innerHTML = addressInput.value;
tr.insertCell().innerHTML = phoneInput.value;
tr.insertCell().innerHTML = '<button class="delete-btn">删除</button>';
// 情况输入框
nameInput.value = addressInput.value = phoneInput.value = '';
};
// 遍历删除按钮 添加单击事件
deleteBtns.forEach(function(deleteBtn){
deleteBtn.onclick = function() {
tableBox.deleteRow(deleteBtn.parentElement.parentElement.rowIndex);
};
});
3. 快速创建 img 元素
new Image();
new Image(宽度,高度);
4. document 对象
document表示整个文档,document是html元素的父节点,document是window的一个属性,document对象具有如下属性方法:
属性 | 含义 |
---|---|
all | 获取到所有元素 |
body | 获取到body元素 |
head | 获取到head元素 |
documentElement | 获取到html根元素 |
lastModify | 获取文档最后一次修改时间 |
title | 获取标题栏标题内容(可读可写) |
cookie | 获取当前文档的cookie信息(可读可写) |
方法 | 含义 |
---|---|
getElementById() | 根据id查找元素 |
getElementsByTagName() | 根据标签名称查找元素 |
getElementsByClassName() | 根据类名查找元素 |
getElementsByName() | 根据name查找元素 |
querySelector() | 查找与选择器匹配的第一个元素 |
querySelectorAll() | 查找匹配的所有元素 |
createElement() | 创建一个由标签名称指定的元素 |