文章目录
- 什么是WebAPI
- DOM 基本概念
- DOM 树
- 事件
- 操作元素
- 获取/修改元素内容
- 获取/修改元素属性
- 获取/修改表单元素属性
- 获取/修改样式属性
- 网页版猜数字游戏
- 实现一个表白墙
什么是WebAPI
前面学习的 JS 分成三个大的部分
- ECMAScript: 基础语法部分
- DOM API: 操作页面结构
- BOM API: 操作浏览器
WebAPI 就包含了 DOM + BOM.
什么是 API
API 是一个更广义的概念. 而 WebAPI 是一个更具体的概念, 特指 DOM+BOM
所谓的 API 本质上就是一些现成的函数/对象, 让程序员拿来就用, 方便开发.
DOM 基本概念
DOM就是文档对象模型
把 html 的每个标签, 都映射到 js 中的一个对应对象
- 标签上显示啥, 都可以通过 js 对象感知到
- js 对象修改对应属性, 能够影响标签的显示
通过 dom 就可以让 js 代码操作页面元素
DOM 树
DOM API 有很多, 在这里只介绍几个常用的.
- 选中页面元素
querySelector (CSS 选择器)
let elem1 = document.querySelector();
这个 document 是浏览器中的全局变量, 任何一个页面都会有一个 document 对象
所有的dom api 都是通过 document 对象来展开的.
<body>
<div class="box">abc</div>
<div id="id">def</div>
<h3>
<span>
<input type="text">
</span>
</h3>
<script>
let elem1 = document.querySelector('.box');
console.log(elem1);
</script>
</body>
我们也可以把这个对象的所有属性都打印出来
<script>
let elem1 = document.querySelector('.box')
// console.log(elem1);
console.dir(elem1);
</script>
<script>
let elem1 = document.querySelector('.box');
// console.log(elem1);
console.dir(elem1);
let elem2 = document.querySelector('#id');
console.log(elem2);
let elem3 = document.querySelector('h3>span>input') ;
console.log(elem3);
</script>
我们前面 css 中学的所有选择器都可以在 querySelector 中使用
事件
事件就是针对用户的一些操作进行的一些响应
要能够和用户交互, 就需要用户干了啥, 用户做的一些动作, 就会在浏览器中产生一些事件(鼠标点击, 鼠标双击, 鼠标按下, 鼠标移动, 调整浏览器窗口… ), 代码就需要针对事件做出反应.
事件的三个要素:
- 事件源: 那个元素产生的事件
- 事件类型: 点击, 双击, 按下…
- 事件处理程序: 事件发生后, 要执行哪个代码. (要执行的代码都是提前设定好的)
前端页面中, 针对事件也是要有不同的处理方式, 都是最开始的时候就设定好的(事件绑定)
最简单的方式, 直接在元素中使用 on… 这样的方法, 来绑定一个事件处理程序
<div class="box" onclick="alert('hello')">abc</div>
但是一般不建议这样写, 容易乱, 特别是一些复杂的事件
<div class="box">abc</div>
<script>
let div = document.querySelector('.box');
div.onclick = function() {
alert('hello');
}
</script>
这样分离开是更好的选择
操作元素
获取/修改元素内容
先获取到该元素, 使用innerHTML 属性, 就能拿到元素里的内容, 修改该属性就会影响到界面的显示
<div class="box">abc</div>
<script>
let div = document.querySelector('.box');
div.onclick = function() {
console.log(div.innerHTML);
}
</script>
chrome 控制台, 默认会把相邻的相同的日志合并
也可以把它关闭
我们也可以修改这个innerHTML
console.log(div.innerHTML);
div.innerHTML += 'a';
获取/修改元素属性
html 的属性也会映射到 js 对象中
<img src="向日葵.jpg" alt="">
<script>
let img = document.querySelector('img');
img.onclick = function() {
console.log(img.src);
img.src ='美女小姐姐.jpg';
}
</script>
其他属性也是都可以设置的.
获取/修改表单元素属性
表单元素(input, textarea, select…) 有一些特别的属性, 普通标签没有的.
value 属性就是获取到元素里用户填写的值.
<input type="text">
<button>点我一下</button>
<script>
let input = document.querySelector('input');
let button = document.querySelector('button');
button.onclick = function() {
console.log(input.value);
}
</script>
下面我们写一个例子
给 input 里放个数字, 每次点击按钮, 让数字+1, 并显示出来
<input type="text">
<button>点我一下</button>
<script>
let input = document.querySelector('input');
let button = document.querySelector('button');
button.onclick = function() {
//console.log(input.value);
let value = parseInt(input.value);
value += 1;
input.value = value;
}
</script>
隐藏密码, 显示密码
<input type="text">
<button>隐藏密码</button>
<script>
let input = document.querySelector('input');
let button = document.querySelector('button');
button.onclick = function() {
if(input.type == 'text') {
input.type = 'password';
button.innerHTML = '显示密码'
} else {
input.type = 'text';
button.innerHTML = '隐藏密码'
}
}
</script>
获取/修改样式属性
- 修改内联样式 (修改style 的值)
我们举个例子
写一个div, 每次点击后字体都放大.
<div style="font-size: 20px;">这是一个div, 点击之后字体放大</div>
<script>
let div = document.querySelector('div');
div.onclick = function() {
// 选获取到当前的字体大小
let fontSize = parseInt(div.style.fontSize);
fontSize += 10;
// 设置字体大小的时候, 不要忘记px这个单位
div.style.fontSize = fontSize + 'px';
}
</script>
这里我们要注意的是, style 里的属性名字都是和 CSS 中一致的(脊柱命名法改成驼峰命名法即可)
- 修改元素应用的 CSS 类名
这里我们也写一个例子, 切换夜间模式
<div id = "one" class="light" style="font-size: 20px; height: 500px;">切换夜间模式和日间模式</div>
<style>
.light {
/* 日间模式 */
color:black;
background-color: white;
}
.dark {
/* 夜间模式 */
color:white;
background-color: black;
}
</style>
<script>
let div = document.querySelector('#one');
div.onclick = function() {
// 点击 div 切换夜间模式和日间模式
if (div.className == 'dark') {
div.className = 'light';
} else {
div.className = 'dark';
}
}
</script>
上面的操作都是针对于当前页面上已有的元素进行展开的.
我们也可以新增或删除
- 新增元素
a. 创建一个元素
b. 把这个元素放到 dom 树种
使用 createElement 方法来创建一个元素
<div class="one">
这是一个div
</div>
<script>
let input = document.createElement('input');
// 让输入框里默认就显示 hello 这个内容
input.value = 'hello'
let div = document.querySelector('.one');
div.appendChild(input);
</script>
<ul>
<li>11</li>
<li>22</li>
</ul>
<script>
let ul = document.querySelector('ul')
for (let i = 3; i < 10; i++) {
let li = document.createElement('li');
li.innerHTML = i + '' + i;
ul.appendChild(li);
}
</script>
- 删除元素
使用 removeChild 删除子节点
<ul>
<li>11</li>
<li>22</li>
</ul>
<script>
let ul = document.querySelector('ul')
for (let i = 3; i < 10; i++) {
let li = document.createElement('li');
li.innerHTML = i + '' + i;
ul.appendChild(li);
}
// 删除 44 这个元素
let toDelete = document.querySelectorAll('li')[3];
console.log(toDelete);
ul.removeChild(toDelete)
</script>
网页版猜数字游戏
生成一个 1~100 之间的随机数
让用户来输入一个数字
根据输入的数字的大小关系给出提示(猜大了, 猜小了, 猜对了)
<!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>
<div>请输入要猜的数字</div>
<input type="text">
<button>提交</button>
<!-- 使用这个div来显示结果 -->
<div class="result"></div>
<script>
// 1. 生成一个1~100的随机整数
// Math.random() 生成的是[0,1) 之间的随机数, 把随机数设为N
// 100*N的范围是[0,100), 这是一个挺长的小数
// 使用parseInt 把小数去掉得到的就是[0~100)的整数了
// 再 +1 就是[1,100]之间的整数了
let toGuess = parseInt(100 * Math.random()) + 1;
console.log(toGuess);
// 2. 进行猜数字操作
let button = document.querySelector('button');
let input = document.querySelector('input');
let resultDiv = document.querySelector('.result')
button.onclick = function() {
// 3. 取出输入框的内容
if (input == '' ) {
// 用户啥都没输入, 直接返回
return;
}
let inputNum = parseInt(input.value);
// 4. 比较大小关系
if (inputNum < toGuess) {
// 猜小了
resultDiv.innerHTML = '猜小了';
} else if (inputNum > toGuess) {
// 猜大了
resultDiv.innerHTML = '猜大了';
} else {
// 猜对了
resultDiv.innerHTML = '恭喜你猜对了';
}
}
</script>
</body>
</html>
实现一个表白墙
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表白墙</title>
<style>
/* * 是一个通配符选择器, 是选中页面所有元素 */
* {
/* 消除浏览器的默认样式 */
margin: 0;
padding: 0;
box-sizing: 0;
}
.container {
width: 600px;
/* 垂直方形为20px 水平方向左右外边距为 auto */
margin: 20px auto;
}
h1 {
text-align: center;
}
p {
text-align: center;
color: #666;
margin: 20px 0;
}
.row {
/* 开启弹性布局 */
display: flex;
height: 40px;
/* 水平方形居中 */
justify-content: center;
/* 垂直方形居中 */
align-items: center;
}
.row span{
width: 60px;
}
.row input {
width: 200px;
height: 30px;
}
.row button {
width: 262px;
height: 30px;
background-color: orange;
/* 去掉边框 */
border: none;
border-radius: 5px;
}
/* 让点击的时候有反馈 */
.row button:active {
background-color: grey;
}
</style>
</head>
<body>
<div class="container">
<h1>表白墙</h1>
<p>输入内容后点击提交信息会显示到下方表格中</p>
<div class="row">
<span>谁</span>
<input type="text">
</div>
<div class="row">
<span>对谁</span>
<input type="text">
</div>
<div class="row">
<span>说</span>
<input type="text">
</div>
<div class="row">
<button id="submit">提交</button>
</div>
<div class="row">
<button id="cancel">撤销</button>
</div>
</div>
<script>
// 实现提交操作, 点击提交按钮,能够把用户输入的内容提交到页面上显示
// 点击的时候, 获取到三个输入框的文本内容
// 创建一个新的 div.row 把内容构造到这个div中
let containerDiv = document.querySelector('.container');
let inputs = document.querySelectorAll('input');
let button = document.querySelector('#submit');
button.onclick = function() {
// 1. 获取到三个输入框的内容
let from = inputs[0].value;
let to = inputs[1].value;
let msg = inputs[2].value;
if (from == '' || to == '' || msg == '') {
return;
}
// 2. 构造一个新的 div
let rowDiv = document.createElement('div');
rowDiv.className = 'row message';
rowDiv.innerHTML = from + ' 对 ' + to + ' 说: ' +msg;
containerDiv.appendChild(rowDiv);
// 3. 清空之前的输入框内容
for (let input of inputs) {
input.value = '';
}
}
let cencelButton = document.querySelector('#cancel');
cencelButton.onclick = function() {
// 删除最后一条消息
// 选中所有的 row, 找到最后一个 row, 然后进行删除
let rows = document.querySelectorAll('.message');
if(rows == null || rows.length ==0) {
return;
}
containerDiv.removeChild(rows[rows.length-1]);
}
</script>
</body>
</html>