diff --git "a/09 \346\233\271\346\255\243\346\263\242/20231208 JavaScript\345\233\276\344\271\246\347\256\241\347\220\206.md" "b/09 \346\233\271\346\255\243\346\263\242/20231208 JavaScript\345\233\276\344\271\246\347\256\241\347\220\206.md"
new file mode 100644
index 0000000000000000000000000000000000000000..b6aed3e329c496f48bb2d16adb72ab1f140ca250
--- /dev/null
+++ "b/09 \346\233\271\346\255\243\346\263\242/20231208 JavaScript\345\233\276\344\271\246\347\256\241\347\220\206.md"
@@ -0,0 +1,236 @@
+# 笔记
+
+我们先看一组代码:在这里创建的json文件和html文件都在同一个文件夹中
+
+//test.josn的代码
+{
+ "reply":"我收到啦!"
+}
+
+const xhr = new XMLHttpRequest();
+xhr.onreadystatechange = () => {
+ if (xhr.readyState !== 4) return;
+ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
+ console.log(xhr.responseText);
+ }
+};
+xhr.open('GET', 'text.json', true);
+xhr.send(null);
+执行结果:
+
+
+
+在这里要啰嗦两句:json文件中的对象键名一定要用双引号包裹,如果属性值里面有字符串,也需要用双引号包裹。
+
+执行步骤
+1.创建xhr对象
+const xhr = new XMLHttpRequest();
+2.利用onreadystatechange属性,封装一个函数,用于监听 readyState的变化。
+xhr.onreadystatechange = () => {
+if (xhr.readyState !== 4) return;
+if (xhr.status >= 200 && xhr.status < 300 ){
+ console.log(xhr.responseText);
+ }
+};
+2.1在xhr对象执行收发数据的时候,它会经历五种状态:
+
+Ajax状态码 状态
+0 (未初始化)未启动
+1 (启动)已经调用 open(),但尚未调用 send()
+2 (发送)发送状态,已经调用 send(),但尚未接收到响应
+3 (接收)已经接收到部分响应数据
+4 (完成)已经接收到全部响应数据,而且已经可以在浏览器中使用了
+加两句console.log()就可以看见状态码的变化了。
+
+
+
+上述的readyStateChange事件是专门用来监听xhr对象的Ajax状态码,只要readyState(也就是Ajax状态码)发生了变化,就会触发这个事件。
+
+
+
+2.2判断HTTP状态码是否为200-299
+
+Ajax状态码为4是不够的,这仅仅表明收到服务器端响应的全部数据,并不能保障数据都是正确的。
+
+所以,我们还需要判断HTTP的状态码,判断xhr对象的status属性值是否在200到300之间(200-299 用于表示请求成功)
+
+if (xhr.status >= 200 && xhr.status < 300 ){
+ console.log(xhr.responseText);
+}
+所以要想请求成功完成,必须要满足上面两个条件。
+
+3.准备发送请求
+xhr.open('GET','text.json', true);
+参数1:选用"GET"或者“POST”的请求方式
+
+参数2:发送请求的地址
+
+参数3:是否异步
+
+4.发送请求
+xhr.send(null)
+ 注意:send() 的参数是通过请求体携带的数据,而GET请求是通过请求头携带数据的,所以要把send的参数置为null
+————————————————
+版权声明:本文为CSDN博主「精通各种hello world的小希」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
+原文链接:https://blog.csdn.net/weixin_50602266/article/details/121910781
+
+# 作业
+
+```js
+/**
+ * 目标1:渲染图书列表
+ * 1.1 获取数据
+ * 1.2 渲染数据
+ */
+const creator = ''
+// 封装-获取并渲染图书列表函数
+function getBooksList() {
+ // 1.1 获取数据
+ axios({
+ url: 'http://hmajax.itheima.net/api/books',
+ params: {
+ // 外号:获取对应数据
+ creator
+ }
+ }).then(result => {
+ // console.log(result)
+ const bookList = result.data.data;
+ // console.log(bookList)
+ // 1.2 渲染数据
+ const htmlStr = bookList.map((item, index) => {
+ return `
+ ${index + 1} |
+ ${item.bookname} |
+ ${item.author} |
+ ${item.publisher} |
+
+ 删除
+ 编辑
+ |
+
`
+ }).join('')
+ // console.log(htmlStr)
+ document.querySelector('.list').innerHTML = htmlStr
+ })
+}
+// 网页加载运行,获取并渲染列表一次
+getBooksList()
+
+/**
+ * 目标2:新增图书
+ * 2.1 新增弹框->显示和隐藏
+ * 2.2 收集表单数据,并提交到服务器保存
+ * 2.3 刷新图书列表
+ */
+// 2.1 创建弹框对象
+const addModalDom = document.querySelector('.add-modal')
+const addModal = new bootstrap.Modal(addModalDom)
+// 保存按钮->点击->隐藏弹框
+document.querySelector('.add-btn').addEventListener('click', () => {
+ // 2.2 收集表单数据,并提交到服务器保存
+ const addForm = document.querySelector('.add-form')
+ const bookObj = serialize(addForm, { hash: true, empty: true })
+ // console.log(bookObj)
+ // 提交到服务器
+ axios({
+ url: 'http://hmajax.itheima.net/api/books',
+ method: 'POST',
+ data: {
+ ...bookObj,
+ creator
+ }
+ }).then(result => {
+ // console.log(result)
+ // 2.3 添加成功后,重新请求并渲染图书列表
+ getBooksList()
+ // 重置表单
+ addForm.reset()
+ // 隐藏弹框
+ addModal.hide()
+ })
+})
+
+/**
+ * 目标3:删除图书
+ * 3.1 删除元素绑定点击事件->获取图书id
+ * 3.2 调用删除接口
+ * 3.3 刷新图书列表
+ */
+// 3.1 删除元素->点击(事件委托)
+document.querySelector('.list').addEventListener('click', e => {
+ // 获取触发事件目标元素
+ // console.log(e.target)
+ // 判断点击的是删除元素
+ if (e.target.classList.contains('del')) {
+ // console.log('点击删除元素')
+ // 获取图书id(自定义属性id)
+ const theId = e.target.parentNode.dataset.id
+ // console.log(theId)
+ // 3.2 调用删除接口
+ axios({
+ url: `http://hmajax.itheima.net/api/books/${theId}`,
+ method: 'DELETE'
+ }).then(() => {
+ // 3.3 刷新图书列表
+ getBooksList()
+ })
+ }
+})
+
+/**
+ * 目标4:编辑图书
+ * 4.1 编辑弹框->显示和隐藏
+ * 4.2 获取当前编辑图书数据->回显到编辑表单中
+ * 4.3 提交保存修改,并刷新列表
+ */
+// 4.1 编辑弹框->显示和隐藏
+const editDom = document.querySelector('.edit-modal')
+const editModal = new bootstrap.Modal(editDom)
+// 编辑元素->点击->弹框显示
+document.querySelector('.list').addEventListener('click', e => {
+ // 判断点击的是否为编辑元素
+ if (e.target.classList.contains('edit')) {
+ // 4.2 获取当前编辑图书数据->回显到编辑表单中
+ const theId = e.target.parentNode.dataset.id
+ axios({
+ url: `http://hmajax.itheima.net/api/books/${theId}`
+ }).then(result => {
+ const bookObj = result.data.data
+ // document.querySelector('.edit-form .bookname').value = bookObj.bookname
+ // document.querySelector('.edit-form .author').value = bookObj.author
+ // 数据对象“属性”和标签“类名”一致
+ // 遍历数据对象,使用属性去获取对应的标签,快速赋值
+ const keys = Object.keys(bookObj) // ['id', 'bookname', 'author', 'publisher']
+ keys.forEach(key => {
+ document.querySelector(`.edit-form .${key}`).value = bookObj[key]
+ })
+ })
+ editModal.show()
+ }
+})
+// 修改按钮->点击->隐藏弹框
+document.querySelector('.edit-btn').addEventListener('click', () => {
+ // 4.3 提交保存修改,并刷新列表
+ const editForm = document.querySelector('.edit-form')
+ const { id, bookname, author, publisher } = serialize(editForm, { hash: true, empty: true})
+ // 保存正在编辑的图书id,隐藏起来:无需让用户修改
+ //
+ axios({
+ url: `http://hmajax.itheima.net/api/books/${id}`,
+ method: 'PUT',
+ data: {
+ bookname,
+ author,
+ publisher,
+ creator
+ }
+ }).then(() => {
+ // 修改成功以后,重新获取并刷新列表
+ getBooksList()
+ // 隐藏弹框
+ editModal.hide()
+ })
+})
+
+```
+