(目录),,Web api文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Document_Object_Model/Introduction,JS 分成三个大的部分:,学习了上述 JS 语法,能做什么? 要想写实际的程序,光会语言是不够的,还需要掌握相关的“生态”。,生态:配套的库/'框架。
,要想操作页面上的元素,就需要先拿到对应的 JS 对象,DOM 中提供了一组 API 能够获取到网页的元素,最重要的两个:,是一个 document 这样的对象的属性,页面中的全局对象,一个页面加载好了,就会自动生成一个全局变量,就叫做document
,这里面就有,一些属性和方法,让我们来操作页面的内容,,但这里有一个问题,如果我们无序列表中列表选项不止一个,会怎么样?,,使用querySelectorAll
,,JS 中的很多代码,都是通过 “事件” 来触发的,事件就是浏览器对于用户的操作行为进行了一个 “统称” (准确的说,事件也不一定全是用户操作产生的,但是大部分是的),例如,鼠标在页面上移动,就会产生一个鼠标移动事件 再例如,鼠标在页面某个位置点击,就会产生一个鼠标点击事件。再例如,鼠标滚轮,来滚动页面,就会产生一组滚动事件。再例如,用户按下键盘的某个按键,也会产生一个键盘事件。再例如,用户修改浏览器窗口大小,也会产生一个窗口大小改变事件,JS 干的一个主要工作,就是在不同的事件中,进行不同的处理,称此函数为
回调函数:这个函数不会立即调用,而是在合适的实际,被 库 / 框架 自动的调用,另一种写法:这个写法,就把页面 (HTML) 写的更乱,我们期望 结构,样式,行为,能够分离,,innerHTML:通过 这个方法,就能获取到 元素的内容。
进一步,就能修改元素的内容。,,那么如果不是文本内容呢?会有什么效果?
,一组标签,,下面,我们在修改对象内容
,该怎么做。,,注意:,innerHTML 得到的是
string 类型,要想进行数字相加,就需要把字符串转成整数
,==由于 JS 是动态类型,转换成数字之后,仍然可以赋值给 valval,就从 string => number 类型==,,,一个 HTML 标签里,能写哪些属性,就同样可以
通过 JS 中的 DOM 对象来获取到一样的属性,,可以通过console.dir
这个方法,
打印出一个 dom 对象的全部属性和值,,表单 (主要是指 input 标签) 的以下属性都可以通过 DOM 来修改,这些属性,都属于表单元素专有的属性,,注意:
,,分成两个步骤:,==创建新节点:==,使用createElement
方法来创建一个元素
,options 参数暂不关注,,此处创建的节点,并没有被挂在 dom 树上
,因此浏览器页面中,是显示不出来的,上面介绍的只是创建元素节点, 还可以使用:,==把节点挂在dom树上:==,使用appendChild
把节点插入到某个节点插入到指定节点的最后一个孩子之后,,还可以使用insertBefore 将节点插入到指定节点前
,,注意1:,,注意2:,一旦一个节点插入完毕, 再针对刚刚的节点对象进行修改, 能够同步影响到 DOM 树中的内容,,删除节点,removeChild
方法来实现,得先拿到
父节点,然后再拿到
待删除的子节点,通过removeChild
就能删除了,,,,刚才咱们写的表白墙程序,是通过一些 div.row 来保存咱们提交的消息,这些 div.row,是挂在 DOM树
上,就是在内存中的,容易失去的
一旦页面刷新 / 关闭了,此时,之前内存中保存的数据,就没了,为了解决上述的数据容易丢失问题,有以下解决方案:,,JS 中的很多代码,都是通过 “事件” 来触发的,
(目录)
什么是 DOM?
文档对象模型 (DOM) 是 HTML 和 XML 文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将 web 页面和脚本或程序语言连接起来。
一个 web 页面是一个文档。这个文档可以在浏览器窗口或作为 HTML 源码显示出来。但上述两个情况中都是同一份文档。文档对象模型(DOM)提供了对同一份文档的另一种表现,存储和操作的方式。 DOM 是 web 页面的完全的面向对象表述,它能够使用如 JavaScript 等脚本语言进行修改。
什么是 DOM 树?
一个页面的结构是一个树形结构,称为 DOM 树
- 文档: 一个页面就是一个 文档,使用
document
表示. - 元素:页面中所有的标签都称为 元素,使用
element
表示. - 节点:网页中所有的内容都可以称为 节点,(标签节点,注释节点,文本节点,属性节点等),使用
node
表示
这些
文档等概念在 JS 代码中就对应一个个的对象
所以才叫
“文档对象模型”
DOM API
Web api文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Document_Object_Model/Introduction
JS 分成三个大的部分:
- ECMAScript: 基础语法部分
- DOM API: 操作页面结构
- BOM API: 操作浏览器
学习了上述 JS 语法,能做什么? 要想写实际的程序,光会语言是不够的,还需要掌握相关的“生态”。
生态:配套的库/'框架。
获取元素
要想操作页面上的元素,就需要先拿到对应的 JS 对象
DOM 中提供了一组 API 能够获取到网页的元素,最重要的两个:
querySelector
querySelectorAll
1、querySelector
是一个 document 这样的对象的属性
页面中的全局对象,一个页面加载好了,就会自动生成一个全局变量,就叫做 document
,这里面就有
一些属性和方法,让我们来操作页面的内容
<!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>Document</title>
</head>
<body>
<div class="one">
hello
</div>
<div id="two">
hello two
</div>
<ul>
<li> aaa </li>
</ul>
<script>
// querySelector 参数就是一个 CSS 的选择器
let div = document.querySelector('.one');
console.log(div);
// id 选择器
let obj = document.querySelector('#two');
console.log(obj);
// 复合选择器
let obj2 = document.querySelectorAll('ul li');
console.log(obj2);
</script>
</body>
</html>
2、querySelectorAll
但这里有一个问题,如果我们无序列表中列表选项不止一个,会怎么样?
使用querySelectorAll
let obj2 = document.querySelectorAll('ul li');
<!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>Document</title>
</head>
<body>
<div class="one">
hello
</div>
<div id="two">
hello two
</div>
<ul>
<li> aaa </li>
<li> bbb </li>
<li> ccc </li>
<li> ddd </li>
<li> eee </li>
</ul>
<script>
// querySelector 参数就是一个 CSS 的选择器
let div = document.querySelector('.one');
console.log(div);
// id 选择器
let obj = document.querySelector('#two');
console.log(obj);
// 复合选择器
let obj2 = document.querySelectorAll('ul li');
console.log(obj2);
</script>
</body>
</html>
事件
1、什么是事件
- JS 要构建动态页面,就需要感知到用户的行为
- 用户对于页面的一些操作(点击,选择,修改等),操作都会在浏览器中产生一个个事件,被 JS 获取到,从而进行更复杂的
交互操作
JS 中的很多代码,都是通过 “事件” 来触发的
事件就是浏览器对于用户的操作行为进行了一个 “统称” (准确的说,事件也不一定全是用户操作产生的,但是大部分是的)
例如,鼠标在页面上移动,就会产生一个鼠标移动事件 再例如,鼠标在页面某个位置点击,就会产生一个鼠标点击事件。再例如,鼠标滚轮,来滚动页面,就会产生一组滚动事件。再例如,用户按下键盘的某个按键,也会产生一个键盘事件。再例如,用户修改浏览器窗口大小,也会产生一个窗口大小改变事件
JS 干的一个主要工作,就是在不同的事件中,进行不同的处理
2、事件三要素
- 事件源 :哪个HTML元素产生的事件.
- 事件类型 :鼠标移动 / 鼠标点击 / 键盘事件 / 窗口大小改变事件…
- 事件的处理程序 :当事件产生之后,执行什么样的 JS 代码,进一步如何处理,往往是一个回调函数
3、点击事件
<!-- 事件源:button -->
<button>这是一个按钮</button>
<script>
let button = document.querySelector('button');
// 事件类型:onclick 事件处理函数:function
button.onclick = function() {
alert('hello');
}
</script>
称此函数为回调函数:这个函数不会立即调用,而是在合适的实际,被 库 / 框架 自动的调用
另一种写法:这个写法,就把页面 (HTML) 写的更乱,我们期望 结构,样式,行为,能够分离
<button onclick="f()">这是一个按钮</button>
<script>
function f() {
alert('hello');
}
</script>
操作元素
操作 == 获取 + 修改
- 操作元素内容
- 操作元素的属性
- 操作元素的样式
1、操作元素内容
通过 对象 里面的一个属性
innerHTML
来实现
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>Document</title>
</head>
<body>
<div id="screen">hello world</div>
<button id="btn">这是一个按钮</button>
<script>
let btn = document.querySelector('#btn');
btn.onclick = function() {
let screen = document.querySelector('#screen');
console.log(screen.innerHTML);
}
</script>
</body>
</html>
上面虽然获得了元素的内容,但是只是一个文本内容。
那么如果不是文本内容呢?会有什么效果?
一组标签
下面,我们在修改对象内容
,该怎么做。
screen.innerHTML='<h1>修改<h1>'
总之,无论是获取对象内容,还是修改对象内容,这两个操作的核心都是 innerHTML。
实现点击数字自增
div 显示整数,一个按钮,每次点击这个按钮,就让里面的整数+1
注意:
innerHTML 得到的是 string 类型,要想进行数字相加,就需要把字符串转成整数
let val = screen.innerHTML;
console.log(typeof(val)); // string
==由于 JS 是动态类型,转换成数字之后,仍然可以赋值给 valval,就从 string => number 类型==
<div id="screen">
0
</div>
<button id="plus">+</button>
<script>
let plusBtn = document.querySelector('#plus');
plusBtn.onclick = function() {
// 1、获取 screen 的值
let screen = document.querySelector('#screen');
let val = screen.innerHTML;
val = parseInt(val);
// 2、将这个值 + 1
val = val + 1;
// 3、把新值写回去
screen.innerHTML = val;
}
</script>
2、操作元素的属性
实现点击切换图片
通过
DOM 对象. 属性名
就可以进行操作了。
<img src="picture1.jpg" alt="">
<script>
let img = document.querySelector('img');
img.onclick = function() {
console.log(img.src); // 打印 src 属性的内容
if (img.src.indexOf('picture1.jpg') >= 0) {
img.src = 'picture2.jpg';
} else if (img.src.indexOf('picture2.jpg') >= 0) {
img.src = 'picture1.jpg';
}
}
</script>
一个 HTML 标签里,能写哪些属性,就同样可以通过 JS 中的 DOM 对象来获取到一样的属性,
可以通过 console.dir
这个方法,打印出一个 dom 对象的全部属性和值
console.dir(img);
3、获取/修改表单元素属性
表单 (主要是指 input 标签) 的以下属性都可以通过 DOM 来修改
value
: input 的值.disabled
: 禁用checked
: 复选框会使用selected
: 下拉框会使用type
: input 的类型(文本, 密码, 按钮, 文件等)
这些属性,都属于表单元素专有的属性
点击计数
使用一个输入框输入初始值(整数). 每次点击按钮, 值 + 1
<input type="text" id="text" value="0">
<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 具有一个重要的属性 value, 这个 value 决定了表单元素的内容
如果是输入框, value 表示输入框的内容
, 修改这个值会影响到界面显式; 在界面上修改这个值也会影响到代码中的属性如果是按钮, value 表示按钮的内容
. 可以通过这个来实现按钮中文本的替换
切换按钮的文本
假设这是个播放按钮, 在 “播放” – “暂停” 之间切换
<input type="button" value="播放">
<script>
let input = document.querySelector('input');
input.onclick = function() {
if (input.value == '播放') {
input.value = '暂停';
} else if (input.value == '暂停') {
input.value = '播放';
}
}
</script>
全选 / 取消全选按钮
实现一个
全选效果
,主要是操作 input 的 checked 属性
- 点击全选按钮,则选中所有选项
- 只要某个选项取消,则自动取消全选按钮的勾选状态
<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、获取元素
let all = document.querySelector('#all');
let girls = document.querySelectorAll('.girl'); //
// 2、给 all 注册点击事件
all.onclick = function() {
for (let i = 0; i < girls.length; i++) {
// all.checked 就是 all 这个复选框的选中状态
girls[i].checked = all.checked;
}
}
// 3、针对每个 girl 注册点击事件,实现对于 all 的取消操作
for (let i = 0; i < girls.length; i++) {
girls[i].onclick = function() {
all.checked = checkGirls(girls);
}
}
function checkGirls(girls) {
// 判断是不是所有的 girl 都被选中了
for (let i = 0; i < girls.length; i++) {
if (!girls[i].checked) {
// 只要有一个是未选中,all 就是未选中状态
return '';
}
}
// 遍历完,所有都是选中状态,就让 all 也是选中状态
return 'checked';
}
</script>
4、操作元素样式
本质上也是操作元素属性
style
对应行内样式 (直接把样式写到 style 里面)className
/classList
对应 内部样式 / 外部样式,应用了一个 / 一组 CSS 类名
4.1 点击加字体大小
let div = document.querySelector('div');
div.onclick = function() {
// 1、获取当前的字体大小
console.log(div.style.fontSize);
}
注意:
1、CSS 不区分大小 写,一般不用驼峰。JS 不能支持
–
作为变量名,不能使用脊柱。所有的 CSS 属性都是同样的规则映射过去的2、当前这里得到 fontSize 是一个字符串,要想相加,就得转成整数 ‘20px’ => parselnt => 20 parselnt 转换的时候,会从头往后去转换,遇到非数字字符 ‘px’ ,就转换停止了
3、当修改CSS属性值的时候,
一定要注意单位
! ! 如果单位不合适 / 遗漏,就会失效
<div style="font-size: 20px;">这是一个文本</div>
<script>
let div = document.querySelector('div');
div.onclick = function() {
// 1、获取当前的字体大小
console.log(parseInt(div.style.fontSize));
let fontSize = parseInt(div.style.fontSize);
// 2、在当前字体大小的基础上,多增加 5px
fontSize += 5;
div.style.fontSize = fontSize + 'px';
}
</script>
4.2 夜间模式
在 HTML 中,表示类名的属性,就是 class
但是在 JS 里,属性名变成了
className
/classList
,为什么不直接使用class
这个名字?
class
在 JS 中也是一个关键字 ( JS ES6 版本以上,也引入了类这个概念)如果要修改的样式比较多,通过 style 来修改就麻烦了,可以直接借助 CSS 类来修改
<style>
.light {
background-color: #fff;
color: #000;
}
.dark {
background-color: #000;
color: #fff;
}
</style>
<div class="light" style="height: 300px;">这是一段话</div>
<button>关灯</button>
<script>
let div = document.querySelector('div');
let button = document.querySelector('button');
button.onclick = function() {
if (div.className == 'light') {
div.className = 'dark';
button.innnerHTML = '开灯';
} else if (div.className == 'dark') {
div.className = 'light';
button.innerHTML = '关灯';
}
}
</script>
4.3 切换颜色
<style>
div {
width: 500px;
height: 300px;
font-size: 20px;
font-weight: bold;
text-align: center;
line-height: 300px;
background-image: url(f:/Photos/520.png);
background-size: 100%, 100%;
}
.one {
color: orange;
}
.two {
color: green;
}
button {
width: 150px;
height: 50px;
background-color: rgb(0, 128, 128);
border-radius: 10px;
border: none;
outline: none;
}
button:active {
background-color: #666;
}
</style>
<div class="one">have a good day!</div><br>
<button style="font-size: 17px;">orange</button>
<script>
let div = document.querySelector('div');
let button = document.querySelector('button');
button.onclick = function() {
if (div.className == 'one') {
div.className = 'two';
button.innerHTML = 'green';
} else if (div.className == 'two') {
div.className = 'one';
button.innerHTML = 'orange';
}
}
</script>
5、操作节点
针对元素操作,其实是操作元素的属性 (元素本身没有发生改变)
针对节点操作,其实是
新增节点 / 删除节点
5.1 新增节点
分成两个步骤:
- 创建元素节点
- 把元素节点插入到 dom 树中
==创建新节点:==
使用 createElement
方法来创建一个元素
,options 参数暂不关注
<script>
let newDiv = document.createElement('div'); // 创建标签
newDiv.id = 'newDiv';
newDiv.className = 'one';
newDiv.innerHTML = 'hello';
console.log(newDiv);
</script>
此处创建的节点,并没有被挂在 dom 树上
,因此浏览器页面中,是显示不出来的
上面介绍的只是创建元素节点, 还可以使用:
- createTextNode 创建文本节点
- createComment 创建注释节点
- createAttribute 创建属性节点
==把节点挂在dom树上:==
使用 appendChild
把节点插入到某个节点插入到指定节点的最后一个孩子之后
<div class="container"></div>
<script>
let newDiv = document.createElement('div'); // 创建标签
newDiv.id = 'newDiv';
newDiv.className = 'one';
newDiv.innerHTML = 'hello';
console.log(newDiv);
let container = document.querySelector('.container');
container.appendChild(newDiv);
</script>
还可以使用 insertBefore 将节点插入到指定节点前
let insertedNode = parentNode.insertBefore(newNode, referenceNode);
- insertedNode 被插入节点(newNode)
- parentNode 新插入节点的父节点
- newNode 用于插入的节点
- referenceNode newNode 将要插在这个节点之前
如果 referenceNode 为 null 则 newNode 将被插入到子节点的末尾.
注意 : referenceNode 引用节点不是可选参数
<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>
注意1:
如果针对一个节点插入两次, 则只有最后一次生效
(相当于把元素移动了)
<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);
// 此处的 children 里有 4 个元素
container.insertBefore(newDiv, container.children[0]);
// 此处的 children 里有 5 个元素(上面新插了一个), 0 号元素是 新节点,
// 1 号元素是 11, 2号节点是 22, 所以是插入到 22 之前.
container.insertBefore(newDiv, container.children[2]);
</script>
注意2:
一旦一个节点插入完毕, 再针对刚刚的节点对象进行修改, 能够同步影响到 DOM 树中的内容
<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]);
// 插入完毕后再次修改 newDiv 的内容
newDiv.innerHTML = '我是新节点2';
</script>
5.2 删除节点
删除节点,removeChild
方法来实现
得先拿到父节点,然后再拿到待删除的子节点,通过 removeChild
就能删除了
oldChild = element.removeChild(child);
- child 为待删除节点
- element 为 child 的父节点
- 返回值为该被删除节点
- 被删除节点只是从 dom 树被删除了, 但是仍然在内存中, 可以随时加入到 dom 树的其他位置.
- 如果上例中的 child节点 不是 element 节点的子节点,则该方法会抛出异常
<div class="container"></div>
<button>删除 div</button>
<script>
let newDiv = document.createElement('div'); // 创建标签
newDiv.id = 'newDiv';
newDiv.className = 'one';
newDiv.innerHTML = 'hello';
console.log(newDiv);
let container = document.querySelector('.container');
container.appendChild(newDiv);
let button = document.querySelector('button');
button.onclick = function() {
container.removeChild(newDiv); // 前面已经获取了
}
</script>
五、代码案例
1、猜数字
Math.random 得到的 [0,1) 随机的 小数 ,如何生成 1 – 100 呢?
先 *100,得到 [0,100) 之间的小数。然后向下取整
Math.floor
,也就是直接舍弃小数部分
<button id="resetBtn">重新开始一局游戏</button> <br>
<span>要猜的数字:</span>
<input type="text">
<button id="guessBtn">猜</button> <br>
<span>结果:</span> <span id="result"></span> <br>
<span>已经猜的次数:</span> <span id="guessCount">0</span>
<script>
// 1、需要用到的元素
let resetBtn = document.querySelector('#resetBtn');
let input = document.querySelector('input');
let guessBtn = document.querySelector('#guessBtn');
let resultSpan = document.querySelector('#result');
let guessCountSpan = document.querySelector('#guessCount');
// 2、生成一个 1 - 100 的随机数
let toGuess = Math.floor(Math.random() * 100) + 1;
console.log(toGuess);
// 3、实现点击 猜 按钮的逻辑
guessBtn.onclick = function() {
// 1) 读取 input 输入的内容,转成整数
if (input.value == '') {
return;
}
let curNum = parseInt(input.value);
// 2) 判断大小 给出提示
if (curNum < toGuess) {
resultSpan.innerHTML = '低了';
resultSpan.style.color = 'red';
} else if (curNum > toGuess) {
resultSpan.innerHTML = '高了';
resultSpan.style.color = 'red';
} else {
resultSpan.innerHTML = '猜对了';
resultSpan.style.color = 'green' ;
}
// 3) 更新猜的次数
let guessCount = parseInt(guessCountSpan.innerHTML);
guessCountSpan.innerHTML = guessCount + 1;
}
// 4、实现 reset 操作,开始游戏
resetBtn.onclick = function() {
// 让页面刷新即可
// location 是和 document 并列关系的对象,用来控制页面的链接/地址,通过 reload 操作就可以刷新页面
location.reload();
}
</script>
2、表白墙
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 100%;
}
h3 {
text-align: center;
padding: 30px 0; /* 上下内边距 20,左右为 0 */
font-size: 24px;
}
p {
text-align: center;
color: #999;
padding: 10px 0;
}
.row {
width: 400px;
height: 50px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
}
.row span {
width: 60px;
font-size: 20px;
}
.row input {
width: 300px;
height: 40px;
line-height: 40px;
font-size: 20px;
text-indent: 0.5em;
/* 去掉输入框的轮廓线 */
outline: none;
}
.row #submit {
width: 200px;
height: 40px;
font-size: 20px;
line-height: 40px;
margin: 0 auto;
color: white;
background-color: orange;
/* 去掉边框 */
border: none;
border-radius: 10px;
}
/* 按下的效果 */
.row #submit:active {
background-color: grey;
}
</style>
<div class="container">
<h3>表白墙</h3>
<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>
<script>
// 当用户点击 submit,就会获取 input 中的内容,把内容构造成一个 div,插入页面末尾
let submitBtn = document.querySelector('#submit');
submitBtn.onclick = function() {
// 1、获取 2 个 input
let inputs = document.querySelectorAll('input');
let from = inputs[0].value;
let to = inputs[1].value;
let msg = inputs[2].value;
if (from == '' || to == '' || msg == '') { // 用户还未填写完毕
return;
}
// 2、生成一个新的 div,内容就是 input 中的内容,新的 div 加到页面中
let div = document.createElement('div');
div.innerHTML = from + ' 对 ' + to + ' 说 ' + msg;
div.className = 'row'; // 应用 row 的样式
let container = document.querySelector('.container');
container.appendChild(div);
// 3、清空之前输入框的内容
for (let i = 0; i < inputs.length; i++) {
inputs[i].value = '';
}
}
</script>
刚才咱们写的表白墙程序,是通过一些 div.row 来保存咱们提交的消息,这些 div.row,是挂在 DOM树
上,就是在内存中的,容易失去的 一旦页面刷新 / 关闭了,此时,之前内存中保存的数据,就没了
为了解决上述的数据容易丢失问题,有以下解决方案:
- 可以把提交的数据,
保存在浏览器本地
( 浏览器提供了localStorage / indexDB
这样的机制,能够实现本地存储),本质上,是通过浏览器,把你要存的数据,存到当前电脑的磁盘上 问题:只有我在自己的电脑上能看到,别人看不到- 可以把提交的数据,通过
网络通信,传输给服务器,由服务器进行保存
- 服务器保存在内存里
- 服务器保存在文件中
- 服务器保存在数据库里
3、待办事项
<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>
<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>
<script>
// 一、实现新增任务
let addTaskButton = document.querySelector('.nav button');
addTaskButton.onclick = function () {
// 1. 获取到任务内容的输入框
let input = document.querySelector('.nav input');
// 2. 获取到输入框内容
let taskContent = input.value;
// 3. 根据内容新建一个元素节点
let row = document.createElement('div');
row.className = 'row';
let checkbox = document.createElement('input');
checkbox.type = 'checkbox';
let span = document.createElement('span');
span.innerHTML = taskContent;
let button = document.createElement('button');
button.innerHTML = '删除';
row.appendChild(checkbox);
row.appendChild(span);
row.appendChild(button);
// 4. 把新节点插入到 todo 中
let todo = document.querySelector('.todo');
todo.appendChild(row);
// 二、点击复选框后将元素放到 "已完成"
// 在事件回调函数中使用 this 能够获取到当前处理事件的元素.
// 通过 this.parentNode 属性能够获取到当前元素的父元素.
// 点击 checkbox 时, 会先修改 value , 再触发点击事件
// 修改 addTaskButton.onclick
// 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);
}
// 三、点击删除按钮删除该任务
// 6. 给删除按钮注册点击事件
button.onclick = function () {
let row = this.parentNode;
let grandParent = row.parentNode;
grandParent.removeChild(row);
}
}
</script>
文章版权声明
1 原创文章作者:言:卍:午,如若转载,请注明出处: https://www.52hwl.com/36597.html
2 温馨提示:软件侵权请联系469472785#qq.com(三天内删除相关链接)资源失效请留言反馈
3 下载提示:如遇蓝奏云无法访问,请修改lanzous(把s修改成x)
4 免责声明:本站为个人博客,所有软件信息均来自网络 修改版软件,加群广告提示为修改者自留,非本站信息,注意鉴别