一、案例效果
如下图,备忘录可添加新事件,对事件进行编辑,删除已有事件,对完成的事件进行标注。
二、涉及要点
1. 事件监听
事件源要与事件绑定后,才能触发对应事件,事件绑定有三种方式:行内事件属性赋值、事件属性赋值、事件监听。
本案例使用了事件监听的方式进行事件绑定,与其他两种方式的区别在于事件属性多次赋值则只会执行最后一次事件处理程序;而事件监听可以添加多个监听器,执行多个事件处理程序。
事件监听格式为:
addEventListener(type, listener, useCapture) //type: 事件类型 //listener: 监听器(处理程序) //useCapture: 默认为false,设置为true时,不会因冒泡触发监听器 //eg: const btn = document.querySelector('button'); btn.addEventListener('click', function() { alert('事件监听') })
2. DOM 节点操作
(1)常用节点获取方法
(2)常用节点信息获取方法
(3)常用节点属性获取方式
(4)DOM 修改
(5)DOM 添加
(6)DOM 删除
3. DOM 控制 CSS 样式
(1)通过 style 属性控制样式
box.style.color = "#fff"; //将元素中文字设置为白色 box.style.marginLeft = "100px"; //将元素左外边距设置为100px
(2)通过classList控制样式:
如果类名存在,则移除它,否则添加它,第二个参数代表无论类名是否存在,强制添加(true)或删除(false)
三、完整代码+详细注释
<!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> button { cursor: pointer; } input { outline: none; background-color: antiquewhite; border: none; border-radius: 3px; width: 250px; height: 30px; margin: 15px; } input::-webkit-input-placeholder { color: #999; } /* 解决li前面的点删除后还占空间的问题 */ ul { padding: 0; margin: 0; } ul>li { list-style: none; } .border { width: 500px; background-color: #999; border-radius: 20px; margin: auto; padding-bottom: 20px; } .border .title { font-size: 24px; color: aliceblue; line-height: 50px; text-align: center; } .form { width: 80%; margin: 15px auto; } .form #add { width: 100px; height: 30px; border-radius: 5px; border: 0; font-weight: 600; font-size: 16px; color: #999; letter-spacing: 6px; } /* 每一条li,代表每一条事件 */ .item { display: flex; justify-content: space-between; line-height: 30px; font-size: 14px; color: rgb(75, 73, 73); padding: 5px 0; border-bottom: 1px solid white; } .item .info { margin-left: 10px; } .list .item .edit, .fin, .del { width: 50px; height: 30px; border: 0; border-radius: 5px; color: white; } .edit { background-color: #337ab7; } .fin { background-color: #20c248; } .del { background-color: #d9534f; } .btn { display: inline-block; width: 180px; margin-right: 0; } /* 点击完成按钮后所添加的新类名finished */ .finished { color: rgb(112, 110, 110); background-color: rgb(197, 190, 190); border-radius: 3px } .finished>.info { /* 为文字添加删除线 */ text-decoration: line-through; } </style> </head> <body> <!-- 备忘录外层边框 --> <div class="border"> <!-- 标题 --> <div class="title">我的备忘录</div> <hr> <!-- 输入框和按钮 --> <div class="form"> <input type="text" name="text" placeholder="请填写您的事件"> <button id="add">添加</button> </div> <!-- 备忘录事件列表 --> <div style="width: 94%;margin: auto;border-radius: 3px;box-shadow: 2px 2px rgb(119, 115, 115);background-color: rgb(214, 219, 219);"> <ul class="list"> <li class="item"> <!-- 事件区域 --> <span class="info">事件1</span> <!-- 按钮区域 --> <div class="btn"> <button class="edit">编辑</button> <button class="fin">完成</button> <button class="del">删除</button> </div> </li> <li class="item"> <!-- 事件区域 --> <span class="info">事件2</span> <!-- 按钮区域 --> <div class="btn"> <button class="edit">编辑</button> <button class="fin">完成</button> <button class="del">删除</button> </div> </li> </ul> </div> </div> </body> <script> var input = document.querySelector('.form input'); //获取事件输入框 var addBtn = document.querySelector('#add'); //获取添加按钮 var list = document.querySelector('.list'); //获取事件列表ul //点击添加按钮 addBtn.addEventListener('click', function () { //使用监听器addEventListener //使用DOM添加insertAdjacentHTML,第一个参数:添加的位置;第二个参数:添加的内容 //每次添加的li均添加到ul内的第一个li之前(afterbegin) list.insertAdjacentHTML('afterbegin', ` <li class="item"> <!-- 事件区域 --> <span class="info">${input.value}</span> <!-- 按钮区域 --> <div class="btn"> <button class="edit">编辑</button> <button class="fin">完成</button> <button class="del">删除</button> </div> </li> `); //由于之前设置点击添加按钮后新元素item会被添加到插入元素内部的第一个子节点之前 //所以我们应该对list的第一个子元素节点进行操作,否则新增事件无法被删除、修改和完成 //删除 list.firstElementChild.querySelector('.del').addEventListener('click', function () { var item = this.parentNode.parentNode item.remove() }) //完成 list.firstElementChild.querySelector('.fin').addEventListener('click', function () { var item = this.parentNode.parentNode item.classList.add('finished') }) //修改 list.firstElementChild.querySelector('.edit').addEventListener('click', function () { var item = this.parentNode.parentNode item.querySelector('.info').innerText = prompt('请修改你的事件:') }) }) var delBtns = document.querySelectorAll('.del'); //获取删除按钮 var finBtns = document.querySelectorAll('.fin'); //获取完成按钮 var editBtns = document.querySelectorAll('.edit'); //获取编辑按钮 //遍历,有几个删除按钮则相当于有几个事件(li) for (var idx = 0; idx < delBtns.length; idx++) { //点击删除按钮 delBtns[idx].addEventListener('click', function () { var item = this.parentNode.parentNode //删除按钮父级的父级,即类名为item的li(该按钮所在的行),一个li即一个事件行 item.remove(); //点击删除按钮后删除该条li }) //点击完成按钮 finBtns[idx].addEventListener('click', function () { var item = this.parentNode.parentNode; //获取该条事件行 //classList属性可以返回一个元素类属性集合 item.classList.add('finished'); //点击完成按钮后为该行添加新类名finished,以实现新样式 }) //点击编辑按钮 editBtns[idx].addEventListener('click', function () { var item = this.parentNode.parentNode; //获取该条事件行 item.querySelector('.info').innerText = prompt('请修改你的事件:'); //点击编辑后将内容插入类名为info的span并弹出系统提示框 }) } </script> </html>