主要内容:
- 查看DOM对象
- 选择、获取DOM对象(标签、id、class、querySelector、querySelectorAll)
- nodelist:child、parent
- DOM元素的动态添加与删除
- 事件,及一个典型的ToDoList操作
1. DOM基本知识 (DOM与事件)
1-1. DOM
- DOM: 文档对象模型
- JS 将整个 HTML/XML 文档看一个对象,也称为 DOM 树
- DOM 树由各种类型的节点组成
1-2. 获取 DOM 元素
- 标签:
document.getElementsByTagName()
- ID:
document.getElementById()
- class:
document.getElementsByClassName()
- API(推荐用):
document.querySelector() / document.querySelectorAll()
1-3. 节点与元素集合
- NodeList: 所有类型的节点集合,包括了元素,文本,注释,片断,文档,属性…
- HTMLColletion: HTML 元素的节点集合 NodeList > HTMLCollection, 是 NodeList 一个子集
1-4. 元素的新增,删除
- 创建元素:
createElement()
- 创建一个元素的片断:
createDocumentFragment()
1-5. 事件
- 事件属性:
on事件名称
- 监听器:
addEventListernaer()
- 事件方法:
函数表达式/匿名函数
2. 查看DOM对象
- 节点是dom中的最小单元
- 节点有: 元素, 文本节点, 注释节点, 片断节点, 文档节点
<!DOCTYPE html>
<html lang="en">
<head>
<title>dom对象</title>
</head>
<body>
<!-- 我们的网站 -->
<h3>hello php.cn</h3>
<p>大家晚上好呀</p>
<script>
// 文档节点
console.log(document);
// 节点类型
console.log(document.nodeType);
// 节点名称
console.log(document.nodeName);
// 节点的值
console.log(document.nodeValue);
// 查看文档类型
console.log(document.doctype);
// 根节点<html>
console.log(document.documentElement);
// 头元素
console.log(document.head);
// 标题
console.log(document.title);
// 主体
console.log(document.body);
document.body.style.backgroundColor = "yellow";
</script>
</body>
</html>
3. 选择、获取DOM对象
<!DOCTYPE html>
<html lang="en">
<head>
<title>如何获取页面元素</title>
</head>
<body>
<div id="list">
<ul class="poster">
<li name="active">战胜疫情, 指日可待</li>
<li>全民动员, 支持国家</li>
<li>我宅家,我骄傲,我为国家省口罩</li>
</ul>
</div>
<!-- <div id="list">hello</div>
<div id="list">world</div> -->
<script>
// 1. 标签: 返回的是一个元素对象的集合
var ul = document.getElementsByTagName("ul");
// console.log(ul);
// console.log(ul[0]);
// console.log(ul.item(0));
// 以上三者的结果是一样的,因为只有一个ul
// 2. id: 只返回具有指定id的第一个元素(唯一)
var list = document.getElementById("list");
// console.log(list);
// id的替代语法
var div = document.getElementsByTagName("div");
// 在返回的div集合中, 选择具有'list'这个标识符的div
// namedItem(id)
console.log(div.namedItem("list"));
console.log(div.namedItem("list") === list);
// namedItem(name)
var lis = document.getElementsByTagName("li");
console.log(lis);
console.log(lis.namedItem("active"));
// 这个很管用,下面是链式获取,并进行格式属性修改。
var active = document.getElementsByTagName("li").namedItem("active");
console.log(active);
active.style.color = "red";
// 在元素级别调用以上的api方法来获取元素
var lis = ul.item(0).getElementsByTagName("li");
console.log(lis);
lis.namedItem("active").style.backgroundColor = "yellow";
// 3. class, 返回一个html集合
var poster = document.getElementsByClassName("poster");
console.log(poster);
poster.item(0).style.border = "1px solid";
// 4. 推荐使用下面的方式
// querySelector(css选择器): 获取满足条件的集合中的第一个元素(类似于id)
// querySelectorAll(css选择器): 获取满足条件的全部元素组成的集合
var div = document.querySelector("#list");
console.log(div);
var li = document.querySelector("#list li");
var li = document.querySelector("#list li:nth-of-type(2)");
var li = document.querySelector("#list li:last-of-type");
console.log(li);
// 获取多个
var lis = document.querySelectorAll(".poster > *");
// 这个地方返回的是nodelist节点列表,而非数组。
console.log(lis);
console.log(lis.item(2));
lis.item(2).style.backgroundColor = "green";
</script>
</body>
</html>
4. node及nodelist:child、parent
<!DOCTYPE html>
<html lang="en">
<head>
<title>node, nodelist</title>
</head>
<body>
<div id="box">
<h2>JavaScript</h2>
<p>通用前端脚本语言</p>
<li>学习让我感到很充实</li>
</div>
<p><a href="https://www.php.cn">PHP中文网</a></p>
<script>
// 页面元素返回类型: HTMLCollection,NodeList
var div = document.querySelector("div");
console.log(div.childNodes);
// nodeType = 3: 文本节点
// console.log(div.childNodes.item(0).nodeType);
// nodeType = 1: 元素节点
// console.log(div.childNodes.item(1).nodeType);
// 过滤掉节点集合中的非元素节点
for (var i = 0; i < div.childNodes.length; i++) {
var currentNode = div.childNodes.item(i);
if (currentNode.nodeType === 1) {
console.log(currentNode.tagName.toLowerCase());
}
}
// chirdren: 只返回父节点中的元素子节点
console.log(div.children);
console.log(div.firstChild); // #text, 文本节点
// 如果只想获取第一个子元素级的节点
console.log(div.firstElementChild);
console.log(div.lastElementChild);
console.log(div.children.item(1));
var li = document.querySelector('li');
console.log(li.parentNode);
// 充当父节点永远不可能是文本或属性,只能是元素或文档
console.log(li.parentElement);
console.log(li.parentElement === li.parentNode);
// 这两个的意思其实是相同的。
</script>
</body>
</html>
5. DOM元素的动态添加与删除
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>元素的动态添加与删除</title>
</head>
<body>
<ul></ul>
<script>
// 创建元素并添加到页面中
var h2 = document.createElement('h2');
// 给元素添加内容
h2.innerText = '大家辛苦了';
// 如果添加的内容带有html标签
// h2.innerText = '大家<span style="color:red">辛苦了</span>';
h2.innerHTML = '大家<span style="color:red">辛苦了</span>';
// 添加到页面中, 必须在父节点上面进行添加
document.body.appendChild(h2);
// 添加多个
var ul = document.querySelector('ul');
// for (var i = 0; i < 10; i++) {
// var li = document.createElement('li');
// li.innerText = '列表项 ' + (i + 1);
// ul.appendChild(li);
// }
// 为防止每添加一个元素导致页面dom树重新渲染一次
// 借助文档片断来解决这个问题
// 先创建一个临时文档片断
var frag = document.createDocumentFragment();
// 将生成的10个li添加到内存中的这个文档片断节点中
for (var i = 0; i < 10; i++) {
var li = document.createElement('li');
li.innerText = '列表项 ' + (i + 1);
frag.appendChild(li);
}
// 将这个文档片断一次性添加到页面, 此时页面只会渲染一次
ul.appendChild(frag);
</script>
</body>
</html>
6. 事件基础
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件基础</title>
</head>
<body>
<!-- 将事件作为元素的一个特殊属性添加到元素上面,用 on为前缀 -->
<button onclick="alert(this.firstChild.nodeValue)">点击我</button>
<button>点我试试看</button>
<a href="https://php.cn">php中文网</a>
<script>
// 获取第二个按钮
var btn = document.querySelector('button:nth-of-type(2)');
// 绑定事件
// addEventListener(type, callback, false)
// 鼠标移入事件: mouseover
btn.addEventListener('mouseover', function (ev) {
// console.log(ev.target);
// ev.target: 触发事件的对象
// console.log(this === ev.target);
ev.target.style = 'width:100px;height:50px;background: lightgreen;outline:none;border:none';
}, false);
// 鼠标移出事件: mouseout
// btn.addEventListener('mouseout', function (ev) {
// // console.log(ev.target);
// // ev.target: 触发事件的对象
// // console.log(this === ev.target);
// ev.target.style = 'none';
// }, false);
// 获取链接
var link = document.links.item(0);
link.onclick = function (ev) {
// 禁止原对象的默认行为
ev.preventDefault();
btn.style = 'none';
};
</script>
</body>
</html>
7. 实战-经典的ToDoList
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>经典的ToDoList</title>
</head>
<body>
<form action="" name="comment" method="post" onsubmit="return false">
<label for="content">请留言:</label>
<input type="text" name="content">
<button>提交</button>
</form>
<ul></ul>
<script>
// 获取表单
var form = document.forms.namedItem('comment');
// 获取留言区
var ul = document.querySelector('ul');
// 监听表单的提交事件
form.addEventListener('submit', function (ev) {
// 禁止原对象的默认行为
ev.preventDefault();
// console.log('事件被监听到了');
// 1. 创建一条新留言
var li = document.createElement('li');
// form.content.value: 留言板内容
if (form.content.value.trim().length === 0) {
alert('内容不能为空');
// 留言框重新获取焦点
form.content.focus();
return false;
} else {
li.innerHTML = form.content.value;
}
// 将留言添加到列表中
// 将最新留言放在最前面显示
// 当留言板为空的时候,直接插入,否则就插入到新一条留言之前
if (ul.childElementCount === 0) {
ul.appendChild(li);
} else {
// insertBefore(要插入的元素, 插入的位置)
ul.insertBefore(li, ul.firstElementChild);
}
// 清空留言框
form.content.value = null;
form.content.focus();
}, false);
</script>
</body>
</html>
8. 实战:添加了删除功能的ToDoList
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>经典的ToDoList-Plus:添加delete功能</title>
</head>
<body>
<form action="" name="comment" method="post" onsubmit="return false">
<label for="content">请留言:</label>
<input type="text" name="content">
<button>提交</button>
</form>
<ul></ul>
<script>
// 获取表单
var form = document.forms.namedItem('comment');
// 获取留言区
var ul = document.querySelector('ul');
// 监听表单的提交事件
form.addEventListener('submit', function (ev) {
// 禁止原对象的默认行为
ev.preventDefault();
// console.log('事件被监听到了');
// 1. 创建一条新留言
var li = document.createElement('li');
// form.content.value: 留言板内容
if (form.content.value.trim().length === 0) {
alert('内容不能为空');
// 留言框重新获取焦点
form.content.focus();
return false;
} else {
li.innerHTML = form.content.value + '<a href="" onclick="del(this)">删除</a>';
}
// 将留言添加到列表中
// 将最新留言放在最前面显示
// 当留言板为空的时候,直接插入,否则就插入到新一条留言之前
if (ul.childElementCount === 0) {
ul.appendChild(li);
} else {
// insertBefor(要插入的元素, 插入的位置)
ul.insertBefore(li, ul.firstElementChild);
}
// 清空留言框
form.content.value = null;
form.content.focus();
}, false);
function del(ele) {
// 禁止原对象的默认行为
this.event.preventDefault();
// console.log(ele.parentElement);
// removeChild()删除子节点
// if (confirm('是否删除?')) {
// ul.removeChild(ele.parentElement);
// }
return confirm('是否删除?') ? ul.removeChild(ele.parentElement) : false;
}
</script>
</body>
</html>
9. 作业
- 实例演示获取页面元素的5种方式(操作了下,基本的东西懂了,后面就看怎么传数据)
- [选做]:
按自己理解重写课堂上的: todolist案例, 实现一个简单的在线客服系统,做一个留言与自动回复功能, 自动回复可以创建一个数组,内置一些写好的文本, 随机打乱输出即可, 试试看