第一章:DOM简介
1.1 什么是DOM?
- 文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准
编程接口
。 - W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式。
1.2 DOM树
- 文档:一个页面就是一个文档,DOM中使用document表示。
- 元素:页面中的所有标签都是元素,DOM中使用element表示。
- 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示。
注意:DOM将以上内容都看做是对象。
第二章:获取元素
2.1 如何获取页面元素?
- DOM在我们实际开发中主要用来操作元素,那么我们如何来获取页面中的元素?
- 获取页面中的元素可以使用以下几种方式:
- ①根据ID获取。
- ②根据标签名获取。
- ③通过HTML5新增的方式获取。
- ④特殊元素获取。
2.2 根据ID获取元素
- 使用getElementById()方法可以获取带有ID的元素对象。
document.getElementById('id');
使用console.dir()可以打印我们获取的元素对象,更好的查看对象里面的属性和方法。
示例:
<!DOCTYPE html>
<html lang="en">
<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>根据ID获取元素</title>
</head>
<body>
<div id="time">2021-11-11</div>
<script>
// 因为文档页面从上往下架子啊,所以必须先有标签。
// 参数 id是大小敏感的字符串
// 返回的是一个元素对象
var time = document.getElementById('time');
console.log(time);
console.log(typeof time); //object
// console.dir() 可以打印元素对象,更好的查看里面的属性和方法
console.dir(time);
</script>
</body>
</html>
2.3 根据标签名获取元素
- 使用getElementsByTagName()方法可以返回带有指定标签名的
对象集合
。
document.getElementsByTagName('标签名');
注意:
- 因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历。
- 得到元素对象是动态的。
- 如果获取不到元素,则返回为空的伪数组(因为获取不到的对象)。
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<ul>
<li>知否知否,应是绿肥红瘦1</li>
<li>知否知否,应是绿肥红瘦2</li>
<li>知否知否,应是绿肥红瘦3</li>
<li>知否知否,应是绿肥红瘦4</li>
<li>知否知否,应是绿肥红瘦5</li>
</ul>
<script>
// 返回的是 元素对象的集合,以伪数组的存储的。
var lis = document.getElementsByTagName('li');
console.log(lis);
console.log(lis[0]);
console.log('------------------------')
// 我们想要依次打印里面的元素对象,可以采取遍历的方式
for (var i = 0; i < lis.length; i++) {
console.log(lis[i]);
}
// 如果页面中只有一个li,返回的还是伪数组的形式。
// 如果页面中没有这个元素,返回的是空的伪数字。
</script>
</body>
</html>
2.4 获取某个元素(父元素)内置所有指定标签名的子元素
- 语法:
element.getElementsByTagName('标签名');
注意:父元素必须是单个对象(
必须指定是哪一个元素对象
)。获取的时候不包括父元素自己。
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<ul>
<li>知否知否,应是绿肥红瘦1</li>
<li>知否知否,应是绿肥红瘦2</li>
<li>知否知否,应是绿肥红瘦3</li>
<li>知否知否,应是绿肥红瘦4</li>
<li>知否知否,应是绿肥红瘦5</li>
</ul>
<ol>
<li>生僻字</li>
<li>生僻字</li>
<li>生僻字</li>
</ol>
<script>
var ol = document.getElementsByTagName('ol')[0];
// 获取某个父元素内部的所有指定标签名的子元素
var li = ol.getElementsByTagName('li');
for (var i = 0; i < li.length; i++) {
console.log(li[i]);
}
</script>
</body>
</html>
2.5 HTML5新增获取元素的方式
- 根据类名返回元素对象集合。
document.getElementsByClassName('类名');
- 根据指定选择器返回第一个元素对象:
document.querySelector('选择器');
- 根据指定选择器返回所有的元素对象:
document.querySelectorAll('选择器');
注意:querySelector和querySelectorAll里面的选择器需要加符号。
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>HTML5新增获取元素的方式</title>
</head>
<body>
<div class="box">盒子</div>
<div class="box">盒子</div>
<div class="nav">
<ul>
<li>首页</li>
<li>产品</li>
</ul>
</div>
<script>
//根据类名返回元素对象集合。
var boxArray = document.getElementsByClassName('box');
for (var i = 0; i < boxArray.length; i++) {
console.log(boxArray[i]);
}
console.log('-----------------------------');
//根据指定选择器返回第一个元素对象:
var liFirst = document.querySelector('.nav ul li');
console.log(liFirst);
console.log('-----------------------------');
//根据指定选择器返回所有的元素对象:
var lis = document.querySelectorAll('.nav ul li');
for (var i = 0; i < lis.length; i++) {
console.log(lis[i]);
}
</script>
</body>
</html>
2.6 获取特殊元素(body、html)
- 获取body元素:
document.body ;//返回body元素对象
- 获取html元素:
document.documentElement ;//返回html元素对象
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>获取特殊元素body和html</title>
</head>
<body>
<script>
//获取body元素
var bodyElement = document.body;
console.log(bodyElement);
//获取html元素
var htmlElement = document.documentElement;
console.log(htmlElement);
</script>
</body>
</html>
第三章:事件基础
3.1 概述
- JavaScript使我们有能力创建动态页面,而事件时可以被JavaScript侦测到的行为。
- 简单理解:触发—响应机制。
- 网页中的每个元素都可以产生某些可以触发JavaScript的事件。例如,我们可以在有用户点击某按钮时产生一个事件,然后去执行某些操作。
3.2 事件三要素
- 事件源(谁)。
- 事件类型(什么事情)。
事件处理程序(做啥)。
示例:
<!DOCTYPE html>
<html lang="en">
<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>
//点击一个按钮,弹出对话框
// 事件是有三部分组成:事件源、事件类型、事件处理程序,我们也称之为事件三要素。
// - 事件源:事件被触发的对象。谁?按钮
var btn = document.getElementById('btn');
// - 事件类型:触发什么事件,比如鼠标点击(onclick)、鼠标经过、键盘按下。
// - 事件处理程序:是通过一个函数赋值的方式完成
btn.onclick = function () {
alert('~~点秋香~~');
}
</script>
</body>
</html>
3.3 执行事件的步骤
- ①获取事件源。
- ②注册事件(绑定事件)。
③添加事件处理程序(采取函数赋值的形式)。
示例:
<!DOCTYPE html>
<html lang="en">
<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>
<div>123</div>
<script>
/*
* - ①获取事件源。
* - ②注册事件(绑定事件)。
* - ③添加事件处理程序(采取函数赋值的形式)。
*/
//点击div,控制台输出,我被选中了
var divElement = document.getElementsByTagName('div')[0];
divElement.onclick = function () {
console.log('~~我被选中了~~');
}
</script>
</body>
</html>
3.4 常见的鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获取鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
第四章:操作元素
4.1 概述
- JavaScript的DOM操作可以改变网页内容、结构和样式,我们可以利用DOM操作元素来改变元素里面的内容、属性等。
注意:以下都是属性。
4.2 改变元素的内容
- 从起始位置到终止位置的内容,会去除html标签,空格和换行。
element.innerText;
- 从起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行。
element.innerHTML;
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<style>
div {
width: 300px;
height: 30px;
line-height: 30px;
color: #fff;
background-color: pink;
}
</style>
</head>
<body>
<button>显示当前的系统时间</button>
<div>某个时间</div>
<script>
/* 当我们点击了按钮,div里面的文字会发生变化 */
// 1. 获取元素
var btn = document.querySelector('button');
var div = document.querySelector('div');
// 2. 注册事件
btn.onclick = function () {
// 改变元素内容
div.innerText = new Date().toLocaleString();
}
</script>
</body>
</html>
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>innerHTML和innerText的区别</title>
</head>
<body>
<div></div>
<p>
我是文字
<span>123</span>
</p>
<script>
//1. innerText 不识别HTML标签 非标准 去掉空格和换行
var div = document.querySelector('div');
// div.innerText = '<b>今天</b>是2021年';
//2. innerHTML 不识别HTML标签 W3C标准 保留空格和换行
div.innerHTML = '<b>今天</b>是2021年';
// innerText和innerHTML可以获取元素中的内容。
var p = document.querySelector('p');
console.log(p.innerText);
console.log(p.innerHTML);
</script>
</body>
</html>
4.3 常用元素的属性操作
- 语法:
innerText、innerHTML 改变元素内容
src、href
id、alt、title
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<style>
img {
width: 200px;
}
</style>
</head>
<body>
<button id="ldh">刘德华</button>
<button id="zxy">张学友</button>
<br>
<br>
<img src="images/ldh.jpg" alt="">
<script>
//1.获取元素
var ldhBtn = document.querySelector('#ldh');
var zxyBtn = document.querySelector('#zxy');
var img = document.querySelector('img');
//2.注册事件 处理程序
ldhBtn.onclick = function () {
img.src = 'images/ldh.jpg';
}
zxyBtn.onclick = function () {
img.src = 'images/zxy.jpg';
}
</script>
</body>
</html>
4.4 表单元素的属性操作
- 利用DOM可以操作如下表单元素的属性:
type、value、checked、selected、disabled
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>按钮</button>
<input type="text" value="输入内容">
<script>
// 获取元素
var btn = document.querySelector('button');
var input = document.querySelector('input');
// 注册事件 处理程序
btn.onclick = function () {
// 表单里面的值 是通过value来修改的
input.value = '被点击了';
// 如果想要某个表单被禁用,不能再点击disabled,我们想要这个按钮禁用。
this.disabled = true;
//this 指向的是事件函数的调用者 btn
}
</script>
</body>
</html>
4.5 样式属性操作
- 可以通过JS修改元素的大小、颜色、位置等样式。
element.style 行内样式操作
element.className 类名样式操作
注意:
- JS里面的样式采取驼峰命名法,如fontSize、backgroundColor;
- JS修改style样式操作,产生的是行内样式,CSS权重比较高。
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<style>
input {
display: block;
width: 320px;
height: 25px;
outline: none;
margin: 100px auto;
color: #999;
}
</style>
</head>
<body>
<input type="text" value="手机">
<script>
/* 当鼠标点击文本框时,里面的默认文字隐藏,当鼠标离开文本框时,里面的文字显示。 */
/* 首先表单需要2个新事件,获得焦点 onfocus 失去焦点 onblur
* 如果获得焦点,判断表单里面内容是否为默认文字,如果是默认文字,就清空表单内容
* 如果失去焦点,判断表单内容是否为空,如果为空,则表单内容改为默认文字
*/
var input = document.querySelector('input');
input.onfocus = function () {
if (this.value == '手机') {
this.value = '';
}
}
input.onblur = function () {
if (this.value == '') {
this.value = '手机';
}
}
</script>
</body>
</html>
4.6 操作元素总结
4.7 自定义属性的操作
4.7.1 获取属性值
element.属性 //获取属性值
element.getAttribute('属性');
区别:
- element.属性;获取内置属性值(元素本身自带的属性)。
- element.getAttribute(‘属性’); 主要获取自定义的属性(标准),程序员自定义的属性。
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<div id="demo" index="1"></div>
<script>
var div = document.querySelector('div');
//1.获取元素的属性值
//1.1 element.属性:获取的是内置的属性值
console.log(div.id);
//1.2 element.getAttribute('属性'):主要获取的是自定义的属性值
console.log(div.getAttribute('id'));
console.log(div.getAttribute('index'));
//2.设置元素的属性值
//2.1 element.属性=值:设置的是内置的属性值
div.id = 'test';
console.log(div.id);
//2.2 element.setAttribute('属性','值'):设置的是自定义的属性值
div.setAttribute('id', 'demo');
console.log(div.id);
div.setAttribute('index', 2);
console.log(div.getAttribute('index'));
</script>
</body>
</html>
4.7.2 设置属性值
element.属性 = '值' //设置内置属性值
element.setAttribute('属性','值');
区别:
- element.属性 = ‘值’; 设置内置属性值。
- element.setAttribute(‘属性’,’值’); 主要设置自定义的属性(标准)。
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<div id="demo" index="1" class="nav"></div>
<script>
var div = document.querySelector('div');
//1.获取元素的属性值
//1.1 element.属性:获取的是内置的属性值
console.log(div.id);
//1.2 element.getAttribute('属性'):主要获取的是自定义的属性值
console.log(div.getAttribute('id'));
console.log(div.getAttribute('index'));
//2.设置元素的属性值
//2.1 element.属性=值:设置的是内置的属性值
div.id = 'test';
console.log(div.id);
div.className = 'navs';
console.log(div.className);
//2.2 element.setAttribute('属性','值'):设置的是自定义的属性值
div.setAttribute('id', 'demo');
console.log(div.id);
div.setAttribute('index', 2);
console.log(div.getAttribute('index'));
div.setAttribute('class', 'footer'); //class特殊,这里写的是class,而不是className
console.log(div.getAttribute('class'));
</script>
</body>
</html>
4.7.3 移除属性
element.removeAttribute('属性');
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<div id="demo" index="1" class="nav"></div>
<script>
var div = document.querySelector('div');
//1.获取元素的属性值
//1.1 element.属性:获取的是内置的属性值
console.log(div.id);
//1.2 element.getAttribute('属性'):主要获取的是自定义的属性值
console.log(div.getAttribute('id'));
console.log(div.getAttribute('index'));
//2.设置元素的属性值
//2.1 element.属性=值:设置的是内置的属性值
div.id = 'test';
console.log(div.id);
div.className = 'navs';
console.log(div.className);
//2.2 element.setAttribute('属性','值'):设置的是自定义的属性值
div.setAttribute('id', 'demo');
console.log(div.id);
div.setAttribute('index', 2);
console.log(div.getAttribute('index'));
div.setAttribute('class', 'footer'); //class特殊,这里写的是class,而不是className
console.log(div.getAttribute('class'));
//3.移除属性
// element.removeAttribute('属性');
div.removeAttribute('index');
console.log(div.getAttribute('index')); //null
</script>
</body>
</html>
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<div id="demo" index="1" class="nav"></div>
<script>
var div = document.querySelector('div');
//1.获取元素的属性值
//1.1 element.属性:获取的是内置的属性值
console.log(div.id);
//1.2 element.getAttribute('属性'):主要获取的是自定义的属性值
console.log(div.getAttribute('id'));
console.log(div.getAttribute('index'));
//2.设置元素的属性值
//2.1 element.属性=值:设置的是内置的属性值
div.id = 'test';
console.log(div.id);
div.className = 'navs';
console.log(div.className);
//2.2 element.setAttribute('属性','值'):设置的是自定义的属性值
div.setAttribute('id', 'demo');
console.log(div.id);
div.setAttribute('index', 2);
console.log(div.getAttribute('index'));
div.setAttribute('class', 'footer'); //class特殊,这里写的是class,而不是className
console.log(div.getAttribute('class'));
//3.移除属性
// element.removeAttribute('属性');
div.removeAttribute('index');
console.log(div.getAttribute('index')); //null
</script>
</body>
</html>
4.8 H5自定义属性
4.8.1 概述
自定义属性的目的:是为了保存并使用数据,有些数据可以保存到页面中而不需要保存到数据库中
。- 自定义属性的获取是通过
getAttribute(‘属性’)
获取的。 - 但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。
- H5给我们新增了自定义属性。
4.8.2 设置H5自定义属性
- H5规定自定义属性
data-
开头做为属性名并且赋值。
<div data-index=“1”></div>
element.setAttribute(‘data-index’, 2)
4.8.3 获取H5自定义属性
- 兼容性获取:
element.getAttribute(‘data-index’);
- H5新增获取自定义属性:
element.dataset.index
element.dataset[‘index’]
4.8.4 应用示例
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>H5自定义属性</title>
</head>
<body>
<!-- H5规定自定义属性data-开头做为属性名并且赋值。 -->
<div data-index="1" data-list-name="哈哈">dd</div>
<script>
/* H5规定自定义属性data-开头做为属性名并且赋值。 */
var div = document.querySelector('div');
div.setAttribute('data-time', 20);
// 兼容性获取:element.getAttribute(‘data-index’);
// H5新增获取自定义属性:element.dataset.index 或 element.dataset[‘index’]
console.log(div.getAttribute('data-index'));
console.log(div.getAttribute('data-list-name'));
console.log(div.dataset.time);
// 如果自定义属性里面有多个-链接的单词,我们获取的时候采取采取驼峰命名法。
console.log(div.dataset.listName);
console.log(div.dataset['listName']);
</script>
</body>
</html>
第五章:节点操作
5.1 为什么学操作节点?
- 获取元素通常有两种方法:
- ①利用DOM提供的方法获取元素。
- document.getElementById();
- document.getElementsByTagName();
- document.querySelector();
- ……
- 逻辑性不强,繁琐。
- ②利用节点层级关系获取元素。
- 利用父子兄弟关系获取元素。
- 逻辑性强,但是兼容性稍差。
- ①利用DOM提供的方法获取元素。
- 这两种方式都可以获取元素节点,后面都会使用,但是节点操作更简单。
5.2 节点的概述
- 网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM中,节点使用node表示。
- HTML DOM树中的所有节点均可通过JavaScript进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。
- 一般的,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
- 元素节点:nodeType=1。
- 属性节点:nodeType=2。
- 文本节点:nodeType=3(文本节点包含文字、空格、换行等)。
我们在实际开发中,节点的操作主要操作的是元素节点
。
5.3 节点层次
5.3.1 概述
- 利用DOM树可以把节点划分为不同的层次关秀,常见的是
父子兄弟关系
。
5.3.2 父节点
node.parentNode
- parentNode属性可以返回某个节点的父节点,注意是
最近的一个父节点
。 如果指定的节点没有父节点则返回null。
示例:
<!DOCTYPE html>
<html lang="en">
<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>
<!-- 节点的优点 -->
<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>
// 父节点parentNode
var erweima = document.querySelector('.erweima');
// var box = document.querySelector('.box');
// 得到的是离元素最近的父级节点,如果找不到父节点返回为null。
var box = erweima.parentNode;
console.log(box);
</script>
</body>
</html>
5.3.3 子节点
//标准
parentNode.childNodes
- parentNode.childNodes返回包含指定节点的子节点的集合,该集合为即时更新的集合。
注意:
返回值里面包含了所有的子节点,包括元素节点、文本节点等。
如果想要获取里面的元素节点,则需要专门处理,所以我们一般不提倡使用childNodes
。
示例:
<!DOCTYPE html>
<html lang="en">
<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>
<!-- 节点的优点 -->
<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>
//获取子节点
//parentNode.childNodes,不提倡使用,太麻烦
var demo = document.querySelector('.demo');
var childNodes = demo.childNodes;
for (var i = 0; i < childNodes.length; i++) {
var childNode = childNodes[i];
//如果是元素节点
if (childNode.nodeType == 1) {
console.log(childNode);
}
}
</script>
</body>
</html>
//非标准
parentNode.children
parentNode.children
是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回(重点掌握
)。虽然children是一个非标准,但是得到了各个浏览器的支持,因此可以放心大胆使用。
示例:
<!DOCTYPE html>
<html lang="en">
<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>
<!-- 节点的优点 -->
<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.childNodes,不提倡使用,太麻烦
var demo = document.querySelector('.demo');
var childNodes = demo.childNodes;
for (var i = 0; i < childNodes.length; i++) {
var childNode = childNodes[i];
//如果是元素节点
if (childNode.nodeType == 1) {
console.log(childNode);
}
}
//2. parentNode.children 提倡使用
var children = demo.children;
for (var i = 0; i < children.length; i++) {
console.log(children[i]);
}
</script>
</body>
</html>
parentNode.firstChild
- firstChild返回的是第一个子节点,找不到则返回null。同样,也是包含所有的节点。
parentNode.lastChild
lastChild返回的是最后一个子节点,找不到则返回null。同样,也是包含所有的节点。
示例:
<!DOCTYPE html>
<html lang="en">
<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>
<ol>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
</ol>
<script>
var ol = document.querySelector('ol');
//firstChild 获取的是第一个子节点,不管是文本节点还是元素节点
console.log(ol.firstChild);
console.log(ol.lastChild);
</script>
</body>
</html>
parentNode.firstElementChild
- firstElementChild返回第一个子元素节点,找不到则返回null。
parentNode.lastElementChild
- lastElementChild返回最后一个子元素节点,找不到则返回null。
注意:
firstElementChild和lastElementChild有兼容性问题,IE9以上才支持
。示例:
<!DOCTYPE html>
<html lang="en">
<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>
<ol>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
</ol>
<script>
var ol = document.querySelector('ol');
//firstChild 获取的是第一个子节点,不管是文本节点还是元素节点
console.log(ol.firstChild);
//lastChild 获取的是最后子节点,不管是文本节点还是元素节点
console.log(ol.lastChild);
//firstElementChild 返回的是第一个子元素节点,IE9+才支持
console.log(ol.firstElementChild);
//lastElementChild 返回的是最后一个子元素节点,IE9+才支持
console.log(ol.lastElementChild);
</script>
</body>
</html>
- 实际开发中,firstChild和lastChild包含其他节点,操作不方便;而firstElementChild和lastElementChild又有兼容性问题,那么我们如何获取第一个子元素节点或者最后一个子元素节点呢?
- 解决方案:
- 如果想要第一个子元素节点,可以使用parentNode.children[0];
- 如果想要最后一个子元素节点,可以使用parentNode.children[parentNode.children.length-1];
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<style>
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
}
li {
list-style: none;
}
.nav {
width: 800px;
margin: 100px auto;
background-color: pink;
}
.nav > li {
position: relative;
width: 80px;
height: 41px;
float: left;
}
.nav li a {
display: block;
font-size: 16px;
width: 100%;
height: 100%;
line-height: 41px;
text-align: center;
color: #333;
}
.nav > li > a:hover {
background-color: #eee;
}
.nav ul {
display: none;
position: absolute;
top: 41px;
left: 0;
width: 100%;
border: 1px solid #FECC5B;
border-top: none;
border-bottom: none;
}
.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="#">微博2</a>
<ul>
<li><a href="#">私信2</a></li>
<li><a href="#">评论2</a></li>
<li><a href="#">@我2</a></li>
</ul>
</li>
<li>
<a href="#">微博3</a>
<ul>
<li><a href="#">私信3</a></li>
<li><a href="#">评论3</a></li>
<li><a href="#">@我3</a></li>
</ul>
</li>
<li>
<a href="#">微博4</a>
<ul>
<li><a href="#">私信4</a></li>
<li><a href="#">评论4</a></li>
<li><a href="#">@我4</a></li>
</ul>
</li>
</ul>
<script>
/*
* 导航栏里面的li 都要有鼠标经过效果,所以需要循环注册鼠标事件
* 核心原理: 当鼠标经过li里面的第二个孩子ul显示,当鼠标离开,则ul 隐藏
*/
var nav = document.querySelector('.nav');
var lis = nav.children;
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function () {
var ul = this.children[this.children.length - 1];
ul.style.display = 'block';
}
lis[i].onmouseout = function () {
var ul = this.children[this.children.length - 1];
ul.style.display = 'none';
}
}
</script>
</body>
</html>
5.3.4 兄弟节点
node.nextSibling
- nextSibling返回当前元素的下一个兄弟元素节点,找不到则返回null。同样,包含所有的节点。
node.previousSibling
- previousSibling返回当前元素的上一个兄弟元素节点,找不到则返回null。同样,包含所有的节点。
node.nextElementSibling
- nextElementSibling返回当前元素的下一个兄弟元素节点,找不到返回null。
node.previousElementSibling
- previousElementSibling返回当前元素的上一个兄弟元素节点,找不到返回null。
注意:nextElementSibling和previousElementSiblin方法有兼容性问题, IE9 以上才支持。
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<div>我是div</div>
<span>我是span</span>
<script>
var div = document.querySelector('div');
//nextSibling: 下一个兄弟节点,包含元素节点或文本节点等等。
console.log(div.nextSibling);
console.log(div.previousSibling);
//nextElementSibling: 下一个兄弟元素节点
console.log(div.nextElementSibling);
console.log(div.previousElementSibling);
</script>
</body>
</html>
5.4 创建节点
document.createElement('tagName');
document.createElement('tagName')
方法创建由tagName指定的HTML元素,因为这些元素原先是不存在的,是根据我们的需求动态生成的,所以我们也称之为动态创建元素节点
。
5.5 添加节点
node.appendChild(child);
node.appendChild(child);
方法将一个节点添加到指定父节点的子节点列表末尾
。类似于CSS中after伪元素。
node.insertBefore(child,指定元素);
node.insertBefore(child,指定元素);
方法将一个节点添加到父节点的指定子节点的前面
。类似于CSS中的before伪元素。示例:
<!DOCTYPE html>
<html lang="en">
<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>
<ul>
<li>123</li>
</ul>
<script>
var ul = document.querySelector('ul');
//创建元素节点
var li = document.createElement('li');
//添加节点:node.appendChild(child) node表示父级,child表示子级 追加元素,类似于数组中的push
ul.appendChild(li);
//添加节点,insertBefore(child,指定元素)
var lili = document.createElement('li');
ul.insertBefore(lili, ul.children[0]);
</script>
</body>
</html>
5.6 删除节点
node.removeChild(child);
node.removeChild(child);
方法从DOM中删除一个子节点,返回删除的节点。示例:
<!DOCTYPE html>
<html lang="en">
<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>
<style>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
}
textarea {
outline: none;
width: 200px;
height: 100px;
border: 1px solid pink;
resize: none;
vertical-align: middle;
}
ul {
margin-top: 50px;
}
</style>
</head>
<body>
<textarea name="" id=""></textarea>
<button>发布</button>
<ul></ul>
<script>
/*
* 当我们把文本域里面的值赋值给li 的时候,多添加一个删除的链接
* 需要把所有的链接获取过来,当我们点击当前的链接的时候,删除当前链接所在的li
* 阻止链接跳转需要添加 javascript:void(0); 或者 javascript:;
*/
var btn = document.querySelector('button');
var ul = document.querySelector('ul');
var textarea = document.querySelector('textarea');
btn.onclick = function () {
var textareaValue = textarea.value;
if (textareaValue) {
//创建元素
var li = document.createElement('li');
//元素赋值
li.innerHTML = textareaValue + '<a href="javascript:void(0);">删除</a>';
//添加元素
ul.insertBefore(li, ul.children[0]);
//删除元素
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function () {
ul.removeChild(this.parentNode)
}
}
}
}
</script>
</body>
</html>
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<style>
* {
margin: 0;
padding: 0;
}
table {
font-size: 16px;
width: 1200px;
margin: 100px auto;
border-collapse: collapse;
}
thead tr {
background-color: #eee;
}
thead tr th {
height: 50px;
}
td {
text-align: center;
height: 30px;
}
th, td {
width: 400px;
border: 1px solid #999;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
//1. 先准备好学生的数据
var datas = [{
name: '魏璎珞',
subject: 'JavaScript',
score: 100
}, {
name: '弘历',
subject: 'Java',
score: 50
}, {
name: '博恒',
subject: 'HTML',
score: 90
}, {
name: '明玉',
subject: 'CSS',
score: 45
}];
//2. 向tbody中创建行
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
//创建行
var tr = document.createElement('tr');
//2. 创建单元格
var data = datas[i];
//行里面创建单元格td 单元格的数量取决于每个对象里面的属性的个数 for循环遍历对象
for (var key in data) {
var td = document.createElement('td');
td.innerHTML = data[key];
tr.append(td);
}
//3. 创建删除单元格
var delTd = document.createElement('td');
delTd.innerHTML = '<a href="javascript:;">删除</a>';
tr.append(delTd);
tbody.append(tr);
//4. 添加删除操作
var as = document.querySelectorAll('a');
for (var j = 0; j < as.length; j++) {
as[j].onclick = function () {
tbody.removeChild(this.parentNode.parentNode);
}
}
}
</script>
</body>
</html>
5.7 复制节点
node.cloneNode()
node.cloneNode()
方法返回调用该方法的节点的一个副本,也称为克隆节点或拷贝节点。
注意:
- 如果括号参数为false或空,则是浅拷贝,即只拷贝节点本身,不拷贝里面的子节点。
- 如果括号参数为true,则是深拷贝,会复制节点本身和里面所有的子节点。
- 示例:
<!DOCTYPE html>
<html lang="en">
<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>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
//将第一个li复制
var li = document.querySelector('li');
ul.insertBefore(li.cloneNode(true), ul.children[0]);
</script>
</body>
</html>
5.8 三种动态创建元素的区别
- 三种动态创建元素的方式:
document.wirte()
。element.innerHTML
。document.createElement()
。
- 三种动态创建元素的区别:
document.wirte()
是直接将内容写入到页面的内容流中,但是文档流执行完毕,它会导致页面全部重绘
。element.innerHTML
是将内容写入到某个DOM节点,不会导致页面全部重绘。element.innerHTML
创建多个元素效率更高,不要用拼接字符串,采用数组形式拼接
,结构稍微复杂。document.createElement()
创建多个元素效率稍微低一点,但是结构更清晰。
总结:不同浏览器下,element.innerHTML的效率要比 document.createElement()高
。
第六章:DOM重点核心
6.1 概述
- 文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。
- W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式。
- 对于JavaScript,为了能够使JavaScript操作HTML,JavaScript就有了一套自己的dom编程接口。
- 对于HTML,dom使得html形成一棵dom树. 包含 文档、元素、节点。
6.2 DOM操作
- 关于dom操作,我们主要针对于元素的操作。主要有创建、增、删、改、查、属性操作、事件操作。
6.2.1 创建
- document.write。
- innerHTML。
- createElement。
6.2.2 增加
- appendChild。
- insertBefore。
6.2.3 删除
- removeChild。
6.2.4 修改
- 主要修改dom的元素属性,dom元素的内容、属性, 表单的值等。
- 修改元素属性: src、href、title等。
- 修改普通元素内容: innerHTML 、innerText。
- 修改表单元素: value、type、disabled等。
- 修改元素样式: style、className
6.2.5 查询
- 主要获取查询dom的元素。
- DOM提供的API 方法: getElementById、getElementsByTagName,古老用法,不太推荐。
- H5提供的新方法: querySelector、querySelectorAll,提倡。
- 利用节点操作获取元素: 父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling) 提倡
6.2.6 属性操作
- 主要针对于自定义属性。
- setAttribute:设置dom的属性值。
- getAttribute:得到dom的属性值。
- removeAttribute移除属性。
6.2.7 事件操作
- 给元素注册事件,采取事件源.事件类型 = 事件处理程序。 | 鼠标事件 | 触发条件 | | —- | —- | | onclick | 鼠标点击左键触发 | | onmouseover | 鼠标经过触发 | | onmouseout | 鼠标离开触发 | | onfocus | 获取鼠标焦点触发 | | onblur | 失去鼠标焦点触发 | | onmousemove | 鼠标移动触发 | | onmouseup | 鼠标弹起触发 | | onmousedown | 鼠标按下触发 |