一、DOM
1.1 获取元素
1.1.1 根据 ID 获取
document.getElementById('id');
1.1.2 根据标签名获取
- 使用
getElementsByTagName()
方法可以返回带有指定标签名的对象的集合。
document.getElementsByTagName('标签名');
- 获取某个元素(父元素)内部所有指定标签名的子元素。
element.getElementsByTagName('标签名');
1.1.3 通过 HTML5 新增的方法获取
- 根据类名返回元素对象集合
document.getElementsByClassName('类名');
- 根据指定选择器返回第一个元素对象
document.querySelector('选择器');
- 根据指定选择器返回
document.querySelectorAll('选择器');
注意:
querySelector
和querySelectorAll
里面的选择器需要加符号,比如:document.querySelector('#nav');
1.1.4 获取特殊元素(body,html)
- 获取body元素
doucumnet.body // 返回body元素对象
- 获取html元素
document.documentElement // 返回html元素对象
- 示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 1.获取 body 元素
var bodyEle = document.body;
console.log(bodyEle);
console.dir(bodyEle);
// 2.获取 html 元素
var htmlEle = document.documentElement;
console.log(htmlEle);
console.dir(htmlEle);
</script>
</body>
</html>
1.2 事件基础
1.2.1 事件三要素
- 事件源 (谁)
- 事件类型 (什么事件)
- 事件处理程序 (做啥)
1.2.2 执行事件的步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采取函数赋值形式)
1.2.3 常见的鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获取鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousesedown | 鼠标按下触发 |
- 案例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>事件三要素</title>
</head>
<body>
<button id="btn">点击一下</button>
<script>
// 点击一个按钮,弹出对话框
// 1.事件是有三部分:事件源、事件类型、事件处理程序
//(1)事件源:事件被触发的对象。谁--按钮
var btn = document.getElementById("btn");
//(2)事件类型:如何触发,什么事件,比如鼠标点击还是鼠标经过,还是键盘按下
//(3)事件处理程序,通过一个函数赋值的方式完成
btn.onclick = function () {
alert("点击了按钮");
};
</script>
</body>
</html>
1.3 操作元素
1.3.1 改变元素内容
- 从起始位置到终止位置的内容, 但它去除 html 标签, 同时空格和换行也会去掉
element.innerText
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div></div>
<script>
// innerText 和 innerHTML的区别 // 1.innerText
var div = document.querySelector("div");
div.innerText = "今天是:2022";
</script>
</body>
</html>
- 起始位置到终止位置的全部内容,包括 html 标签,同时保留空格和换行
element.innerHTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div></div>
<script>
// innerText 和 innerHTML的区别
// 1.innerText
var div = document.querySelector("div");
// div.innerText = "今天是:2022";
// 2.innerHTML
div.innerHTML = "<strong>今天是:</strong> 2022";
</script>
</body>
</html>
1.3.2 常见元素的属性操作
- innerText innerHTML 改变元素内容
- src href
- id alt title
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
img {
width: 300px;
}
</style>
</head>
<body>
<button id="ldh">刘德华</button>
<button id="zxy">张学友</button><br />
<img src="images/ldh.jpg" alt="" />
<script>
// 修改元素属性
// 1.获取元素
var ldh = document.getElementById("ldh");
var zxy = document.getElementById("zxy");
var img = document.querySelector("img");
// 2.注册事件
ldh.onclick = function () {
img.src = "images/ldh.jpg";
};
zxy.onclick = function () {
img.src = "images/zxy.jpg";
};
</script>
</body>
</html>
1.3.3 表单元素的属性操作
type value checked selected disabled
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button>按钮</button>
<input type="text" value="输入内容" />
<script>
// 1.获取元素
var btn = document.querySelector("button");
var input = document.querySelector("input");
// 2.注册事件 处理程序
btn.onclick = function () {
// 表单里面的值,文字内容是通过 value来修改的
input.value = "被点击了";
};
</script>
</body>
</html>
1.3.4 样式属性操作
- element.style 行内样式操作
- element.className 类名样式操作
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
var div = document.querySelector("div");
div.onclick = function () {
// div.style.backgroundColor = "green";
// div.style里面的属性,采用驼峰命名法
this.style.backgroundColor = "purple";
this.style.width = "250px";
};
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
.change {
background-color: purple;
color: #fff;
font-size: 25px;
margin-top: 100px;
}
</style>
</head>
<body>
<div>文本</div>
<script>
var div = document.querySelector("div");
div.onclick = function () {
// this.style.backgroundColor = "purple";
// this.style.color = "#fff";
// this.style.fontSize = "25px";
// this.style.marginTop = "100px";
// 让我们当前元素的类名改为了 change
this.className = "change";
};
</script>
</body>
</html>
1.3.5 排他思想
- 案例
如果有同一组元素,我们想要某一个元素实现某种样式, 需要用到循环的排他思想算法:
- 所有元素全部清除样式(干掉其他人)
- 给当前元素设置样式 (留下我自己)
- 注意顺序不能颠倒,首先干掉其他人,再设置自己
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
// 1.获取所有按钮元素
var btns = document.getElementsByTagName("button");
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
// (1)我们先把所有的按钮背景颜色去掉
for (var i = 0; i < btns.length; i++) {
btns[i].style.backgroundColor = "";
}
// (2)然后才让当前的元素背景颜色为 pink
this.style.backgroundColor = "pink";
};
}
</script>
</body>
</html>
1.3.6 自定义属性的操作
- 获取属性值
element.属性 获取属性值。
element.getAttribute(‘属性’);
区别:
- element.属性 获取内置属性值(元素本身自带的属性)
- element.getAttribute(‘属性’); 主要获得自定义的属性 (标准) 我们程序员自定义的属性
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="demo" index="1"></div>
<script>
var div = document.querySelector("div");
// 1.获取元素的属性值
// (1)element.属性
console.log(div.id);
// (2)element.getAttribute('属性')
// get 得到,获取 attribute 属性的意思
console.log(div.getAttribute("id"));
console.log(div.getAttribute("index"));
</script>
</body>
</html>
- 设置属性值
element.属性 = ‘值’ 设置内置属性值。
element.setAttribute(‘属性’, ‘值’);
区别:
- element.属性 设置内置属性
- element.setAttribute(‘属性’); 主要设置自定义的属性 (标准)
- 移除属性
- element.removeAttribute(‘属性’);
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="demo" index="1" class="nav"></div>
<script>
var div = document.querySelector("div");
// 1.获取元素的属性值
// (1)element.属性
console.log(div.id);
// (2)element.getAttribute('属性')
// get 得到,获取 attribute 属性的意思
console.log(div.getAttribute("id"));
console.log(div.getAttribute("index"));
// 2.设置元素属性值
// (1)element.属性 = '值';
div.id = "test";
div.className = "navs";
// (2)element.setAttribute(‘属性’);
div.setAttribute("index", "2");
div.setAttribute("class", "footer");
// 3.移除属性 element.removeAttribute('属性');
div.removeAttribute("index");
</script>
</body>
</html>
1.4 节点操作
1.4.1 节点层级
- 父级节点
node.parentNode
- parentNode 属性可返回某节点的父节点,注意是最近的一个父节点
- 如果指定的节点没有父节点则返回 null
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>我是div</div>
<span>我是span</span>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<div class="demo">
<div class="box">
<div class="erweima">x</div>
</div>
</div>
<script>
// 1. 父节点 parentNode
var erweima = document.querySelector(".erweima");
// var box = document.querySelector('.box');
// 得到的是离元素最近的父级节点,如果找不到父节点就返回为 null
console.log(erweima.parentNode);
</script>
</body>
</html>
- 子节点
1. parentNode.childNode //标准
2. parentNode.children //非标准
-
parentNode.childNodes
返回包含指定节点的子节点的集合,该集合为即时更新的集合。
注意:返回值里面包含了所有的子节点,包括元素节点,文本节点等。
如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes -
parentNode.children
是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回 (这个是我们重点掌握的)。
虽然children 是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用。 -
案例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>我是div</div>
<span>我是span</span>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<ol>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ol>
<div class="demo">
<div class="box">
<div class="erweima">x</div>
</div>
</div>
<script>
// DOM 提供的方法 (API) 获取
var ul = document.querySelector("ul");
// var lis = ul.querySelect('li');
// 1.子节点 childNodes 所有的子节点,包含:元素节点,文本节点等等
console.log(ul.childNodes);
// 1.children 获取所有的子节点元素 也是我们实际开发常用的
console.log(ul.children);
</script>
</body>
</html>
3. parentNode.firstChild
4. parentNode.lastChild
5. parentNode.firstElementChild
6. parentNode.lastElementChild
- firstChild 返回第一个子节点,找不到则返回null。同样,也是包含所有的节点。
- lastChild 返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点。
- firstElementChild 返回第一个子元素节点,找不到则返回null。
- lastElementChild 返回最后一个子元素节点,找不到则返回null。
注意:firstElementChild和lastElementChild,这两个方法有兼容性问题,IE9 以上才支持。
实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而 firstElementChild 和 lastElementChild 又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?
解决方案:
如果想要第一个子元素节点,可以使用 parentNode.chilren[0]
如果想要最后一个子元素节点,可以使用 parentNode.chilren[parentNode.chilren.length - 1]
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<ol>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
</ol>
<script>
var ol = document.querySelector("ol");
// 1.firstChild 第一个子节点,不管是文本节点还是元素节点
console.log(ol.firstChild);
// 2.lastChild 最后一个子节点,不管是文本节点还是元素节点
console.log(ol.lastChild);
// 3.firstElementChild 返回第一个子元素节点
console.log(ol.firstElementChild);
// 4.lastElementChild 返回最后一个子元素节点
console.log(ol.lastElementChild);
// 5.实际开发的写法,既没有兼容性问题又返回第一个子元素
console.log(ol.children[0]);
// 6.实际开发的写法,既没有兼容性问题又返回最后一个子元素
console.log(ol.children[ol.children.length - 1]);
</script>
</body>
</html>
- 兄弟节点
1. node.nextSibling
2. node.previousSibling
- nextSibling 返回当前元素的下一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
- previousSibling 返回当前元素上一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
3. node.nextElementSibling
4. node.previousElementSibling
- nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null。
- previousElementSibling 返回当前元素上一个兄弟节点,找不到则返回null。
注意:这两个方法有兼容性问题, IE9 以上才支持。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>我是div</div>
<span>我是span</span>
<script>
var div = document.querySelector("div");
console.log(div.nextSibling);
console.log(div.previousSibling);
console.log(div.nextElementSibling);
console.log(div.previousElementSibling);
</script>
</body>
</html>
1.4.2 创建节点
document.createElement('tagName')
document.createElement() 方法创建由 tagName 指定的 HTML 元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点。
1.4.3 添加节点
1. node.appendChild(child)
2. node.insertBefore(child, 指定元素)
- node.appendChild() 方法将一个节点添加到指定父节点的子节点列表末尾。类似于 CSS 里面的 after 伪元素。
- node.insertBefore() 方法将一个节点添加到父节点的指定子节点前面。类似于 CSS 里面的 before 伪元素。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<ul>
<li>123</li>
</ul>
<script>
// 1.创建节点元素节点
var li = document.createElement("li");
// 2.添加节点 node.appendChild(child) node 父级 child 子级 后面追加元素 类似于数组中的push
var ul = document.querySelector("ul");
ul.appendChild(li);
// 3.添加节点 node.insertBefore(child, 指定元素);
var lili = document.createElement("li");
ul.insertBefore(lili, ul.children[0]);
</script>
</body>
</html>
1.4.4 删除节点
node.removeChild(child)
- node.removeChild() 方法从 DOM 中删除一个子节点,返回删除的节点。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button>删除</button>
<ul>
<li>熊大</li>
<li>熊二</li>
<li>光头强</li>
</ul>
<script>
// 1.获取元素
var ul = document.querySelector("ul");
var btn = document.querySelector("button");
// 2.删除元素 node.removeChild(child)
btn.onclick = function () {
if (ul.children.length == 0) {
this.disabled = true;
} else {
ul.removeChild(ul.children[0]);
}
};
</script>
</body>
</html>
1.4.5 复制节点(克隆节点)
node.cloneNode()
node.cloneNode() 方法返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点
注意:
- 如果括号参数为空或者为 false ,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
- 如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector("ul");
// 1.node.cloneNode();括号为空或者里面是false是浅拷贝,只复制标签不复制里面的内容
// 2.node.cloneNode(true);括号为true是深拷贝,既复制标签又复制里面的内容
var lili = ul.children[0].cloneNode();
ul.appendChild(lili);
var lili = ul.children[0].cloneNode(true);
ul.appendChild(lili);
</script>
</body>
</html>
1.4.6 三种动态创建元素区别
- document.write()
- element.innerHTML
- document.createElement()
区别
-
document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
-
innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘
-
innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
-
createElement() 创建多个元素效率稍低一点点,但是结构更清晰
总结:不同浏览器下,innerHTML 效率要比 creatElement 高
1.5 DOM 重点核心
关于dom操作,我们主要针对于元素的操作。主要有创建、增、删、改、查、属性操作、事件操作。
- 创建
- document.write
- innerHTML
- createElement
- 增
- appendChild
- insertBefore
- 删
- removeChild
- 改
主要修改dom的元素属性,dom元素的内容、属性, 表单的值等
- 修改元素属性: src、href、title等
- 修改普通元素内容: innerHTML 、innerText
- 修改表单元素: value、type、disabled等
- 修改元素样式: style、className
- 查
主要获取查询dom的元素
-
DOM提供的API 方法: getElementById、getElementsByTagName 古老用法 不太推荐
-
H5提供的新方法: querySelector、querySelectorAll 提倡
-
利用节点操作获取元素: 父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling) 提倡
- 属性操作
主要针对于自定义属性。
- setAttribute:设置dom的属性值
- getAttribute:得到dom的属性值
- removeAttribute移除属性
- 事件操作
给元素注册事件, 采取 事件源.事件类型 = 事件处理程序
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获取鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousesedown | 鼠标按下触发 |