JavaScript(WebAPI)
WebAPI概述
什么是WebAPI
⚡️ 前面学习的js分成三个大部分:
☁️ ECMAScript:基础语法部分;
☁️ DOM API:操作页面结构;
☁️ BOM API:操作浏览器;
⚡️ WebAPI就包含了DOM+BOM;
什么是API?
⚡️ API是一个更广义的概念,而WebAPI是一个更具体的概念,特指DOM+BOM;
⚡️ 所谓的API本质上就是一些现成的函数/对象,让我们可以直接拿来用,这个概念在我们学习面向对象思想的时候就已经很熟悉了;
API参考文档
⚡️ https://developer.mozilla.org/zh-CN/docs/Web/API在此网站中,按照“MDN+API关键字”的方式,可以快速搜索到需要的API文档;
DOM基本概念
什么是DOM
⚡️ DOM全称为Document Object Model;
⚡️ DOM可以用来操作:网页内容、网页结构、网页样式;
DOM树
⚡️ 一个页面的结构是一个树形结构,称为DOM树;
☁️ Document:即文档,一个页面就是一个文档;
☁️ element:即元素,页面中所有的标签都称为元素;
☁️ node:即节点,网页中所有的内容都可以称为节点;
获取元素
⚡️ 是一个类似于CSS选择器的功能;
querySelector
querySelectorAll
事件初识
基本概念
⚡️ JavaScript要构建动态页面,就需要感知用户的行为;
⚡️ 用户对于页面的一些操作都会在浏览器中产生一个个事件,从而被JavaScript获取到,并作出交互回应;
事件的三要素
⚡️ 事件源:哪个元素触发的;
⚡️ 事件类型:是点击还是选中还是输入等等;
⚡️ 事件处理程序:进一步如何处理(往往使用回调函数);
示例
<button id="btn">点我一下</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
alert("hello world");
}
</script>
⚡️ btn就是事件源,当鼠标点击btn,这个点击就是事件类型,function函数就是事件处理程序;
⚡️ btn(事件源)——>鼠标点击(事件类型)——>触发function函数(事件处理程序)
操作元素
获取/修改元素内容
1、innerText
☁️ Element.innerText 属性表示一个节点及其后代的“渲染”文本内容;
<div>
<span>hello world</span>
<span>hello world</span>
</div>
<script>
// 读取 div 内部内容
var div = document.querySelector('div');
// 修改 div 内部内容, 界面上就会同步修改
console.log(div.innerText);
//修改时文本覆盖了两个span标签
div.innerText = 'hello js <span>hello js</span>';
</script>
☁️ 写入时是用单引号中的内容覆盖两个span标签并全部输出;
☁️ 读取时只读取span标签内的内容;
2、innerHTML
☁️ Element.innerHTML 属性设置或获取HTML语法表示的元素的后代;
<div>
<span>hello world</span>
<span>hello world</span>
</div>
<script>
var div = document.querySelector('div');
// 读取页面内容
console.log(div.innerHTML);
// 修改页面内容
div.innerHTML = '<span>hello js</span>'
</script>
☁️ 输出时并不是输出单引号内的全部内容,而是去掉span标签;
☁️ 读取时连span标签一并读取并输出;
获取修改元素属性
☁️ 可以通过Element对象的属性来直接修改,就能影响到页面显示效果;
<img src="https://ts1.cn.mm.bing.net/th/id/R-C.a4738e6fe1ba72ce474dedebb5ef305d?rik=bVE73AAdyTyYtA&riu=http%3a%2f%2fwww.2qqtouxiang.com%2fpic%2fPF6988_04.jpg&ehk=nNnJAXfrg0MqCyVAXvlat5aESF8tlyUqzF0%2bCTdFpxs%3d&risl=&pid=ImgRaw&r=0" alt="这是机器猫" title="小叮当">
<script>
var img = document.querySelector('img');
console.dir(img);
</script>
☁️ 此时可以看到 img 这个 Element 对象中有很多属性;
☁️ 我们可以使用代码来直接获取这些属性的值:
<img src="https://ts1.cn.mm.bing.net/th/id/R-C.a4738e6fe1ba72ce474dedebb5ef305d?rik=bVE73AAdyTyYtA&riu=http%3a%2f%2fwww.2qqtouxiang.com%2fpic%2fPF6988_04.jpg&ehk=nNnJAXfrg0MqCyVAXvlat5aESF8tlyUqzF0%2bCTdFpxs%3d&risl=&pid=ImgRaw&r=0" alt="这是机器猫" title="小叮当">
<script>
var img = document.querySelector('img');
// console.dir(img);
console.log(img.src);
console.log(img.title);
console.log(img.alt);
</script>
☁️ 输出结果为:
☁️ 还可以通过代码直接修改属性:
<img src="https://ts1.cn.mm.bing.net/th/id/R-C.a4738e6fe1ba72ce474dedebb5ef305d?rik=bVE73AAdyTyYtA&riu=http%3a%2f%2fwww.2qqtouxiang.com%2fpic%2fPF6988_04.jpg&ehk=nNnJAXfrg0MqCyVAXvlat5aESF8tlyUqzF0%2bCTdFpxs%3d&risl=&pid=ImgRaw&r=0" alt="这是机器猫" title="小叮当">
<script>
var img = document.querySelector('img');
img.onclick = function () {
if (img.src.lastIndexOf('https://ts1.cn.mm.bing.net/th/id/R-C.a4738e6fe1ba72ce474dedebb5ef305d?rik=bVE73AAdyTyYtA&riu=http%3a%2f%2fwww.2qqtouxiang.com%2fpic%2fPF6988_04.jpg&ehk=nNnJAXfrg0MqCyVAXvlat5aESF8tlyUqzF0%2bCTdFpxs%3d&risl=&pid=ImgRaw&r=0') !== -1) {
img.src = 'https://scpic.chinaz.net/files/pic/pic9/201410/apic7241.jpg';
} else {
img.src = 'https://ts1.cn.mm.bing.net/th/id/R-C.a4738e6fe1ba72ce474dedebb5ef305d?rik=bVE73AAdyTyYtA&riu=http%3a%2f%2fwww.2qqtouxiang.com%2fpic%2fPF6988_04.jpg&ehk=nNnJAXfrg0MqCyVAXvlat5aESF8tlyUqzF0%2bCTdFpxs%3d&risl=&pid=ImgRaw&r=0';
}
}
</script>
获取/修改表单元素属性
☁️ 表单就是指input标签,input标签的属性都可以通过DOM来修改;
⚡️ value:input的值;
⚡️ disabled:禁用;
⚡️ checked:复选框使用;
⚡️ selected:下拉框使用;
⚡️ type:用于设置input的类型;
☁️ 代码示例:“播放 - 暂停”切换按钮;
<input type="button" value="播放">
<script>
var btn = document.querySelector('input');
btn.onclick = function () {
if (btn.value === '播放') {
btn.value = '暂停';
} else {
btn.value = '播放';
}
}
</script>
☁️ 代码示例: 使用一个输入框输入初始值(整数),每次点击按钮,值 + 1;
<input type="text" id="text" value="0"> //value等于几文本框里就显示几
<input type="button" id="btn" value='点我+1'>
<script>
var text = document.querySelector('#text');
var btn = document.querySelector('#btn');
btn.onclick = function () {
var num = +text.value;
console.log(num);
num++;
text.value = num;
}
</script>
☁️ 代码示例:全选/取消全选;
<input type="checkbox" id="all">我全都要 <br>
<input type="checkbox" class="girl">貂蝉 <br>
<input type="checkbox" class="girl">小乔 <br>
<input type="checkbox" class="girl">安琪拉 <br>
<input type="checkbox" class="girl">妲己 <br>
<script>
// 1. 获取到元素
var all = document.querySelector('#all');
var girls = document.querySelectorAll('.girl');
// 2. 给 all 注册点击事件, 选中/取消所有选项
all.onclick = function () {
for (var i = 0; i < girls.length; i++) {
girls[i].checked = all.checked;
}
}
// 3. 给 girl 注册点击事件
for (var i = 0; i < girls.length; i++) {
girls[i].onclick = function () {
// 检测当前是不是所有的 girl 都被选中了.
all.checked = checkGirls(girls);
}
}
// 4. 实现 checkGirls
function checkGirls(girls) {
for (var i = 0; i < girls.length; i++) {
if (!girls[i].checked) {
// 只要一个 girl 没被选中, 就认为结果是 false(找到了反例)
return false;
}
}
// 所有 girl 中都没找到反例, 结果就是全选中
return true;
}
</script>
☁️ 效果如下图:
获取/修改样式属性
☁️ CSS中指定元素的属性,都可以通过JS来修改;
行内样式操作
☁️ 代码示例:点击文字则放大字体;
<div style="font-size: 20px; font-weight: 700;">
哈哈
</div>
<script>
var div = document.querySelector('div');
div.onclick = function () {
var curFontSize = parseInt(this.style.fontSize);
curFontSize += 10;
this.style.fontSize = curFontSize + "px";
}
</script>
类名样式操作
☁️ 代码示例:开启夜间模式; 点击页面切换到夜间模式(背景变成黑色) 再次点击恢复日间模式(背景变成白色 ;
<div class="container light">
锄禾日当午 <br>
汗滴禾下土 <br>
谁知盘中餐 <br>
粒粒皆辛苦 <br>
</div>
<style>
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
}
.container {
width: 100%;
height: 100%;
}
.light {
background-color: #f3f3f3;
color: #333;
}
.dark {
background-color: #333;
color: #f3f3f3;
}
</style>
<script>
var div = document.querySelector('div');
div.onclick = function () {
console.log(div.className);
if (div.className.indexOf('light') != -1) {
div.className = 'container dark';
} else {
div.className = 'container light';
}
}
</script>
☁️ 效果如下图:
操作节点
新增节点
☁️ 一共分为两步:1、创建元素节点;2、将元素节点插入到dom树中;
☁️ 创建元素节点:使用createElement方法来创建一个元素.options参数暂不关注;
<div class="container">
</div>
<script>
var div = document.createElement('div');
div.id = 'mydiv';
div.className = 'box';
div.innerHTML = 'hehe';
console.log(div);
</script>
☁️ 此时发现, 虽然创建出新的 div 了, 但是 div 并没有显示在页面上. 这是因为新创建的节点并没有加入到 DOM 树中 ;
☁️ 将节点插入到dom树中:
<div class="container">
</div>
<script>
var div = document.createElement('div');
div.id = 'mydiv';
div.className = 'box';
div.innerHTML = 'hehe';
var container = document.querySelector('.container');
container.appendChild(div);
</script>
☁️ 或:
<div class="container">
<div>11</div>
<div>22</div>
<div>33</div>
<div>44</div>
</div>
<script>
var newDiv = document.createElement('div');
newDiv.innerHTML = '我是新的节点';
var container = document.querySelector('.container');
console.log(container.children);
container.insertBefore(newDiv, container.children[0]);
</script>
删除节点
☁️ 使用removeChild删除子节点;
代码案例:猜数字;
<button type="button" id="reset">重新开始一局游戏</button>
<br>
请输入要猜的数字:<input type="text" id="number">
<button type="button" id="button">猜</button>
<br>
已经猜的次数:<span id="count">0</span>
<br>
结果:<span id="result"></span>
<script>
var inputE = document.querySelector("#number");
var countE = document.querySelector("#count");
var resultE = document.querySelector("#result");
var btn = document.querySelector("#button");
var resetBtn = document.querySelector("#reset");
// 随机生成一个 1-100 的数字
var guessNumber = Math.floor(Math.random() * 100) + 1// 0 - 1 之间的数
var count = 0;
// on: 当
// click: 点击
// 事件驱动(Event-Drive):只要真正发生了点击事件时,才执行该函数
btn.onclick = function() {
count++;
countE.innerText = count;
var userGuess = parseInt(inputE.value);
if (userGuess == guessNumber) {
resultE.innerText = "猜对了";
resultE.style = "color: gray;";
} else if (userGuess < guessNumber) {
resultE.innerText = "猜小了";
resultE.style = "color: blue;";
} else {
resultE.innerText = "猜大了";
resultE.style = "color: red;";
}
};
resetBtn.onclick = function() {
guessNumber = Math.floor(Math.random() * 100) + 1
count = 0;
countE.innerText = count;
resultE.innerText = "";
inputE.value = "";
}
</script>
代码案例:表白墙
☁️ 创建页面布局:
<h1>表白墙</h1>
<p>输入后点击提交, 会将信息显示在表格中</p>
<span>谁: </span>
<input type="text">
<span>对谁: </span>
<input type="text">
<span>说什么: </span>
<input type="text">
<input type="button" value="提交">
☁️ 调整样式:
<div class="container">
<h1>表白墙</h1>
<p>输入后点击提交, 会将信息显示在表格中</p>
<div class="row">
<span>谁: </span>
<input class="edit" type="text">
</div>
<div class="row">
<span>对谁: </span>
<input class="edit" type="text">
</div>
<div class="row">
<span>说什么: </span>
<input class="edit" type="text">
</div>
<div class="row">
<input type="button" value="提交" class="submit">
</div>
</div>
<style>
* {
margin: 0;
padding: 0;
}
.container {
width: 400px;
margin: 0 auto;
}
h1 {
text-align: center;
padding: 20px 0;
}
p {
color: #666;
text-align: center;
font-size: 14px;
padding: 10px 0;
}
.row {
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
span {
width: 100px;
line-height: 40px;
}
.edit {
width: 200px;
height: 30px;
}
.submit {
width: 304px;
height: 40px;
color: white;
background-color: orange;
border: none;
}
</style>
☁️ 实现提交:
// 给点击按钮注册点击事件
var submit = document.querySelector('.submit');
submit.onclick = function () {
// 1. 获取到编辑框内容
var edits = document.querySelectorAll('.edit');
var from = edits[0].value;
var to = edits[1].value;
var message = edits[2].value;
console.log(from + "," + to + "," + message);
if (from == '' || to == '' || message == '') {
return;
}
// 2. 构造 html 元素
var row = document.createElement('div');
row.className = 'row';
row.innerHTML = from + '对' + to + '说: ' + message;
// 3. 把构造好的元素添加进去
var container = document.querySelector('.container');
container.appendChild(row);
// 4. 同时清理之前输入框的内容
for (var i = 0; i < 3; i++) {
edits[i].value = '';
}
}
☁️ 完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>Document</title>
</head>
<body>
<div class="container">
<h1>表白墙</h1>
<p>输入后点击提交, 会将信息显示在表格中</p>
<div class="row">
<span>谁: </span>
<input class="edit" type="text">
</div>
<div class="row">
<span>对谁: </span>
<input class="edit" type="text">
</div>
<div class="row">
<span>说什么: </span>
<input class="edit" type="text">
</div>
<div class="row">
<input type="button" value="提交" class="submit">
</div>
</div>
<style>
* {
margin: 0;
padding: 0;
}
.container {
width: 400px;
margin: 0 auto;
}
h1 {
text-align: center;
padding: 20px 0;
}
p {
color: #666;
text-align: center;
font-size: 14px;
padding: 10px 0;
}
.row {
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
span {
width: 100px;
line-height: 40px;
}
.edit {
width: 200px;
height: 30px;
}
.submit {
width: 304px;
height: 40px;
color: white;
background-color: orange;
border: none;
}
</style>
<script>
// 给点击按钮注册点击事件
var submit = document.querySelector('.submit');
submit.onclick = function () {
// 1. 获取到编辑框内容
var edits = document.querySelectorAll('.edit');
var from = edits[0].value;
var to = edits[1].value;
var message = edits[2].value;
console.log(from + "," + to + "," + message);
if (from == '' || to == '' || message == '') {
return;
}
// 2. 构造 html 元素
var row = document.createElement('div');
row.className = 'row';
row.innerHTML = from + '对' + to + '说: ' + message;
// 3. 把构造好的元素添加进去
var container = document.querySelector('.container');
container.appendChild(row);
// 4. 同时清理之前输入框的内容
for (var i = 0; i < 3; i++) {
edits[i].value = '';
}
}
</script>
</body>
</html>
☁️ 最后效果:
代码案例:待办事项
☁️ 创建页面布局:
<div class="nav">
<input type="text">
<button>新建任务</button>
</div>
<div class="container">
<div class="todo">
<h3>未完成</h3>
<div class="row">
<input type="checkbox">
<span>吃饭</span>
<button>删除</button>
</div>
</div>
<div class="done">
<h3>已完成</h3>
</div>
</div>
☁️ 实现页面样式:
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 800px;
margin: 0 auto;
display: flex;
}
.todo,
.done {
width: 50%;
height: 100%;
}
.container h3 {
height: 50px;
text-align: center;
line-height: 50px;
background-color: #333;
color: #fff;
}
.nav {
width: 800px;
height: 100px;
margin: 0 auto;
display: flex;
align-items: center;
}
.nav input {
width: 600px;
height: 50px;
}
.nav button {
width: 200px;
height: 50px;
border: none;
background-color: orange;
color: #fff;
}
.row {
height: 50px;
display: flex;
align-items: center;
}
.row input {
margin: 0 10px;
}
.row span {
width: 300px;
}
.row button {
width: 50px;
height: 40px;
}
</style>
☁️ 实现页面行为:
⚡️ 实现新增:
// 实现新增任务
var addTaskButton = document.querySelector('.nav button');
addTaskButton.onclick = function () {
// 1. 获取到任务内容的输入框
var input = document.querySelector('.nav input');
// 2. 获取到输入框内容
var taskContent = input.value;
// 3. 根据内容新建一个元素节点
var row = document.createElement('div');
row.className = 'row';
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
var span = document.createElement('span');
span.innerHTML = taskContent;
var button = document.createElement('button');
button.innerHTML = '删除';
row.appendChild(checkbox);
row.appendChild(span);
row.appendChild(button);
// 4. 把新节点插入到 todo 中
var todo = document.querySelector('.todo');
todo.appendChild(row);
}
☁️ 点击复选框后将元素放到“已完成”:
// 修改 addTaskButton.onclick
addTaskButton.onclick = function () {
// 上方的部分不变...
// 5. 给 checkbox 注册点击事件
checkbox.onclick = function () {
var row = this.parentNode;
// 注意! 是先触发 checked 为 true, 然后再调用 onclick 函数
if (this.checked) {
var target = document.querySelector('.done');
} else {
var target = document.querySelector('.todo');
}
target.appendChild(row);
}
}
☁️ 实现删除该任务功能
// 修改 addTaskButton.onclick
addTaskButton.onclick = function () {
// 上方的部分不变...
// 6. 给删除按钮注册点击事件
button.onclick = function () {
var row = this.parentNode;
var grandParent = row.parentNode;
grandParent.removeChild(row);
}
}
do’);
todo.appendChild(row);
}
:cloud: 点击复选框后将元素放到“已完成”:
```javascript
// 修改 addTaskButton.onclick
addTaskButton.onclick = function () {
// 上方的部分不变...
// 5. 给 checkbox 注册点击事件
checkbox.onclick = function () {
var row = this.parentNode;
// 注意! 是先触发 checked 为 true, 然后再调用 onclick 函数
if (this.checked) {
var target = document.querySelector('.done');
} else {
var target = document.querySelector('.todo');
}
target.appendChild(row);
}
}
☁️ 实现删除该任务功能
// 修改 addTaskButton.onclick
addTaskButton.onclick = function () {
// 上方的部分不变...
// 6. 给删除按钮注册点击事件
button.onclick = function () {
var row = this.parentNode;
var grandParent = row.parentNode;
grandParent.removeChild(row);
}
}