diff --git "a/07 \345\210\230\346\226\207\351\224\213/20231214\344\275\234\344\270\232.md" "b/07 \345\210\230\346\226\207\351\224\213/20231214\344\275\234\344\270\232.md"
new file mode 100644
index 0000000000000000000000000000000000000000..e705637409a6d48bede539266c383869a88b30fc
--- /dev/null
+++ "b/07 \345\210\230\346\226\207\351\224\213/20231214\344\275\234\344\270\232.md"
@@ -0,0 +1,248 @@
+### tab栏切换
+
+~~~ js
+// 1. 给 ul 添加点击事件(事件委托)
+$('ul').on('click','a',function(){
+ // 先删除 li里的 active
+ $('a.active').removeClass('active')
+ // 自己添加 active 类
+ $(this).addClass('active')
+
+ // 先删除 有item类 里的 active
+ $('.item.active').removeClass('active')
+ // 获取当前点击的 a 的索引
+ const id = $('a').index($(this))
+ // 根据 id 指定某个div添加 active 类
+ $(`.item:eq(${id})`).addClass('active')
+})
+~~~
+
+### 轮播图
+
+~~~ js
+// 定义起始值
+let i = 0
+// 1. 给 > 按钮 添加点击事件
+$('.next').bind('click', () => {
+ // 判断 i 是否大于数组长度
+ i = i >= sliderData.length - 1 ? 0 : i + 1
+ // 调用切换函数
+ toggleData()
+})
+
+// 2. 给 < 按钮添加点击事件
+$('.prev').bind('click', () => {
+ // 判断 i 是否大于数组长度
+ i = i <= 0 ? sliderData.length - 1 : i - 1
+ // 调用切换函数
+ toggleData()
+})
+
+// 3. 添加定时器
+let time = setInterval(() => {
+ $('.next').click()
+}, 1000)
+
+// 4. 添加 鼠标经过、移出事件
+$('.slider-wrapper,.slider-footer').bind({
+ 'mouseover': () => {
+ // console.log(111);
+ // 暂停定时器
+ clearInterval(time)
+ },
+ 'mouseout': () => {
+ // console.log(222);
+ // 开启定时器
+ time = setInterval(() => {
+ $('.next').click()
+ }, 1000)
+ }
+})
+
+// 分装一个切换(图片、标题、背景颜色、小圆点)的类
+function toggleData() {
+ // 切换图片
+ $('.slider-wrapper img').attr('src', sliderData[i].url)
+ // 切换标题
+ $('.slider-footer p').html(sliderData[i].title)
+ // 切换标题背景颜色
+ $('.slider-footer').css('background', sliderData[i].color)
+ // 切换小圆点
+ // 先删除 active 类
+ $('.slider-indicator li.active').removeClass('active')
+ // 自己添加 active 类
+ $(`.slider-indicator li:eq(${i})`).addClass('active')
+}
+~~~
+
+### 图书管理系统
+
+~~~ js
+/**
+ * 目标一: 获取接口数据并渲染
+ * 1.1 定义自己的外号
+ * 1.2 通过自己的外号,发送异步请求,获取数据
+ * 1.3 将获取的数据渲染
+ */
+
+// 1.1 定义自己的外号
+const creator = '墨下皆是心酸'
+
+// 因为,添加、删除、编辑后都要渲染一遍,所有分装一个渲染函数
+function getBooksList() {
+ // 1.2 通过自己的外号,发送异步请求,获取数据
+ $.ajax({
+ url: 'https://hmajax.itheima.net/api/books',
+ data: {
+ creator
+ },
+ success: (result) => {
+ const data = result.data
+ // 将获取的数据渲染到页面上
+ const htmlStr = $.map(data, (item, index) => {
+ // 解构数据
+ const { id, bookname, author, publisher } = item
+ return `
+
+ ${index + 1} |
+ ${bookname} |
+ ${author} |
+ ${publisher} |
+
+ 删除
+ 编辑
+ |
+
+ `
+ }).join('')
+ $('tbody').html(htmlStr)
+ }
+ })
+}
+getBooksList()
+
+
+/**
+ * 目标二:添加图书
+ * 2.1 获取添加弹框d对象
+ * 2.2 给保存按钮添加点击事件,收集表单信息,隐藏弹框
+ * 2.3 通过获取的表单内容,发送异步请求
+ * 2.4 清空表单,刷新图书列表
+*/
+
+// 2.1 获取 添加弹框 对象
+const addModal = new bootstrap.Modal($('.add-modal'))
+
+// 2.2 给保存按钮添加点击事件,收集表单信息,隐藏弹框
+$('.add-btn').bind('click', () => {
+ // 获取 添加弹框 中的表单对象
+ const addForm = $('.add-form')[0]
+ // 使用表单插件,获取表单信息
+ const objBook = serialize(addForm, { hash: true, empty: true })
+ console.log(objBook);
+ // 2.3 通过获取的表单内容,发送异步请求
+ $.ajax({
+ url: 'https://hmajax.itheima.net/api/books',
+ type: 'post',
+ data: {
+ ...objBook,
+ creator
+ },
+ success: () => {
+ // 2.4 清空表单,刷新图书列表
+ // console.log(result);
+ // 刷新图书列表
+ getBooksList()
+ // 隐藏 添加弹框
+ addModal.hide()
+ // 清空表单
+ addForm.reset()
+ }
+ })
+})
+
+
+/**
+ * 目标三:删除图书
+ * 3.1 给 tbody 添加点击事件(事件委托)
+ * 3.2 通过自定义属性,向接口发送异步请求,删除图书
+ * 3.3 刷新图书列表
+ */
+
+$('tbody').on('click', '.del', function () {
+ // 是否删除弹框(提高数据安全性)
+ if (confirm('你确定要删除吗?')) {
+ // 获得父级身上的自定义属性
+ const id = $(this).parent().data('id')
+ // console.log(id);
+ // 3.2 通过自定义属性,向接口发送异步请求,删除图书
+ $.ajax({
+ url: `https://hmajax.itheima.net/api/books/${id}`,
+ type: 'delete',
+ success: () => {
+ // 3.3 刷新图书列表
+ getBooksList()
+ }
+ })
+ }
+})
+
+
+/**
+ * 目标四:修改图书
+ * 4.1 给 tbody 添加点击事件(事件委托),显示弹框
+ * 4.2 通过 id 发送异步请求,获取当前图书的信息,回显在表单上
+ * 4.3 点击 修改 将修改后的数据提交给异步请求,隐藏弹框,刷新表单页面
+ */
+
+
+// 获取 编辑弹框对象
+const editModal = new bootstrap.Modal($('.edit-modal'))
+// 4.1 给 tbody 添加点击事件(事件委托),显示弹框
+$('tbody').on('click', '.edit', function () {
+ // 获得父级身上的自定义属性
+ const id = $(this).parent().data('id')
+ // 4.2 通过 id 发送异步请求,获取当前图书的信息,回显在表单上
+ $.ajax({
+ url: `https://hmajax.itheima.net/api/books/${id}`,
+ success: result => {
+ // 因为,获取到的数据的 key 名刚好是每个表单的 类名
+ // 所以,可以先获取响应数据中的所有 key,遍历回显
+ const bookInfo = result.data
+ // console.log(bookInfo);
+ const keys = Object.keys(bookInfo)
+ // console.log(keys);
+ keys.forEach(key => {
+ document.querySelector(`.edit-form .${key}`).value = bookInfo[key]
+ })
+ // 显示弹框
+ editModal.show()
+ }
+ })
+})
+
+
+// 获取编辑弹框中的表单对象
+const editForm = $('.edit-form')[0]
+// 4.3 点击 修改 将修改后的数据提交给异步请求,隐藏弹框,刷新表单页面
+$('.edit-btn').bind('click', () => {
+ // 使用插件获取表单信息,并解构
+ const objBook = serialize(editForm, { hash: true, empty: true })
+ // console.log(objBook);
+ // 将修改后的数据提交给异步请求
+ $.ajax({
+ url: `https://hmajax.itheima.net/api/books/${objBook.id}`,
+ type: 'put',
+ data: {
+ ...objBook,
+ creator
+ },
+ success: result => {
+ // 隐藏弹框
+ editModal.hide()
+ // 刷新图书列表
+ getBooksList()
+ }
+ })
+})
+~~~
\ No newline at end of file