1. bootstrap弹框
2. 案例1_图书管理
// 自己的图书数据: 给自己起个外号
const creator = "chl";// 获取-图书列表
function render() {axios({url: "https://hmajax.itheima.net/api/books",params: {creator,},}).then((res) => {// console.log(res.data.data);let str = res.data.data.map((item, index) => {const { id, bookname, author, publisher } = item;return `<tr><td>${index + 1}</td><td>${bookname}</td><td>${author}</td><td>${publisher}</td><td><span class="del" data-id="${id}">删除</span><span class="edit" data-id="${id}">编辑</span></td></tr>`;}).join("");document.querySelector(".list").innerHTML = str;});
}
render();const editModal = document.querySelector(".edit-modal");
const modalEdit = new bootstrap.Modal(editModal);// 删除+编辑-事件委托
let id = "";
document.querySelector(".list").addEventListener("click", function (e) {id = e.target.dataset.id;// console.log(id);// 删除-图书if (e.target.classList.contains("del")) {axios({url: `https://hmajax.itheima.net/api/books/${id}`,method: "DELETE",}).then((res) => {render();});}// 编辑if (e.target.classList.contains("edit")) {// console.log(e.target.parentNode.parentNode); // trmodalEdit.show();// 获取-图书详情axios({url: `https://hmajax.itheima.net/api/books/${id}`,}).then((res) => {// console.log(res);// console.log(res.data.data);// 解构 剩余参数 对象方法/* const { id, ...other } = res.data.data;const oValues = Object.values(other);// console.log(other);Object.keys(other).forEach((key, index) => {document.querySelector(`.edit-form .${key}`).value = oValues[index];}); */// for in遍历对象 key是属性名 获取属性值->对象名[属性名]for (const key in res.data.data) {document.querySelector(`.edit-form .${key}`).value = res.data.data[key];}/* document.querySelector(`.edit-form .bookname`).value =res.data.data.bookname;document.querySelector(`.edit-form .author`).value = res.data.data.author;document.querySelector(`.edit-form .publisher`).value =res.data.data.publisher; */});}
});// 编辑 确认修改按钮
const editBtn = document.querySelector(".edit-btn");
editBtn.addEventListener("click", function () {const editForm = document.querySelector(".edit-form");const data = serialize(editForm, { hash: true, empty: true });// 修改-图书详情axios({url: `https://hmajax.itheima.net/api/books/${id}`,method: "PUT",data: {...data,creator,},}).then((res) => {render();modalEdit.hide();});
});// 新增-图书
const addBtn = document.querySelector(".add-btn");
const addModal = document.querySelector(".add-modal");
const modalAdd = new bootstrap.Modal(addModal);
addBtn.addEventListener("click", function () {// serialize 获取表单值const addForm = document.querySelector(".add-form");const data = serialize(addForm, { hash: true, empty: true });// console.log(data); // {bookname: '12', author: '12', publisher: '12'}axios({url: "https://hmajax.itheima.net/api/books",method: "post",data: {// 展开运算符,解构data...data,/* bookname,author,publisher, */creator,},}).then((res) => {// console.log(res);render();modalAdd.hide();// console.log(Object.keys(data)); // ['bookname', 'author', 'publisher']// 增加后表单数据置空,data对象内属性名和所需找的标签类名相同 --> forEachObject.keys(data).forEach((key) => {document.querySelector(`.add-form .${key}`).value = "";});});
});
3. 案例2_图片上传
<!DOCTYPE html>
<html lang="zh-CN"><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><style>.img {width: 200px;}</style>
</head><body><!-- file标签 --><input type="file" class="upload"><!-- 渲染服务器返回的图片URL --><img src="" class="img" alt=""><!-- 导入axios --><!-- <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.2.0/axios.min.js"></script> --><script src="./axios.min.js"></script><script>/*** 图片上传* 1. 选择图片* 2. FormData对象* 3. 调用上传接口* */const upload = document.querySelector('.upload')upload.addEventListener('change', function () {// FormData内置对象,负责向服务器传递表单数据,常用于文件上传const data = new FormData()data.append('img', this.files[0])// 调用上传接口axios({url: 'https://hmajax.itheima.net/api/uploadimg',method: 'post',// data:formData对象data,}).then(res => {// console.log(res.data)document.querySelector('.img').src = res.data.data.url})})</script>
</body></html>
4. 案例3_网站换肤
const skin = document.querySelector("#skin");
skin.addEventListener("change", function () {const data = new FormData();data.append("img", this.files[0]);axios({url: "https://hmajax.itheima.net/api/uploadimg",method: "post",data,}).then((res) => {// document.body.style.backgroundImage = `url(${res.data.data.url})`;// 本地存储localStorage.setItem("url", res.data.data.url);document.body.style.backgroundImage = `url(${localStorage.getItem("url")})`;});
});
document.body.style.backgroundImage = `url(${localStorage.getItem("url") || ""
} )`;
5. 案例4_个人设置
html
<!DOCTYPE html>
<html lang="zh-CN"><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"><!-- 导入bootstrap --><!-- <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet"> --><!-- 核心样式 --><link rel="stylesheet" href="./css/index.css"><title>个人设置</title>
</head><body><!-- toast 提示框 --><div class="toast my-toast" data-bs-autohide="true" data-bs-delay="1500" aria-live="assertive" aria-atomic="true"role="alert"><div class="toast-body"><div class="alert alert-success info-box" role="alert">操作成功</div></div></div><!-- 核心内容区域 --><div class="container"><ul class="my-nav"><li class="active">基本设置</li><li>安全设置</li><li>账号绑定</li><li>新消息通知</li></ul><div class="content"><div class="info-wrap"><h3 class="title">基本设置</h3><form class="user-form" action="javascript:;"><div class="form-item"><label for="email">邮箱</label><input id="email" name="email" class="email" type="text" placeholder="请输入邮箱" autocomplete="off"></div><div class="form-item"><label for="nickname">昵称</label><input id="nickname" name="nickname" class="nickname" type="text" placeholder="请输入昵称" autocomplete="off"></div><div class="form-item"><label>性别</label><label class="male-label"><input type="radio" name="gender" class="gender" value="0">男</label><label class="male-label"><input type="radio" name="gender" class="gender" value="1">女</label></div><div class="form-item"><label for="desc">个人简介</label><textarea id="desc" name="desc" class="desc" placeholder="请输入个人简介" cols="20" rows="10"autocomplete="off"></textarea></div><button class="submit">提交</button></form></div><div class="avatar-box"><h4 class="avatar-title">头像</h3><img class="avatar" src="./img/头像.png" alt=""><label for="upload">更换头像</label><input id="upload" type="file"></div></div></div><!-- 导入 axios --><!-- <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.2.0/axios.min.js"></script> --><script src="../axios.min.js"></script><!-- 导入 bootstrap --><!-- <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/js/bootstrap.min.js"></script> --><!-- 导入 form-serialize --><script src="./lib/form-serialize.js"></script><!-- 核心逻辑 --><script src="./js/index.js"></script>
</body></html>
js
// 修改-个人头像
const upload = document.querySelector("#upload");
const creator = "chl";
upload.addEventListener("change", function () {const data = new FormData();data.append("avatar", this.files[0]);data.append("creator", creator);axios({url: "https://hmajax.itheima.net/api/avatar",method: "put",data,}).then((res) => {// console.log(res.data);document.querySelector(".avatar").src = res.data.data.avatar;});
});// 获取-个人信息
function getData() {axios({url: "https://hmajax.itheima.net/api/settings",params: {creator,},}).then((res) => {// 方法一:解构并渲染到页面// const {} = res.data.data;// console.log(res.data.data);// 方法二:将要获取的元素类名和数据对象属性名相同 --> 遍历Object.keys(res.data.data).forEach((key) => {if (key == "avatar") {document.querySelector(".avatar").src = res.data.data[key];} else if (key == "gender") {const genders = document.querySelectorAll(".gender");genders[res.data.data[key]].checked = true;} else {document.querySelector(`.${key}`).value = res.data.data[key];}});});
}
getData();// 修改-个人信息
document.querySelector(".submit").addEventListener("click", function () {const userForm = document.querySelector(".user-form");const data = serialize(userForm, { hash: true, empty: true });// console.log(data);// serialize获取到的data数据为字符串,axios请求时其gender数据类型应为数字类型 --> 数据类型转换data.gender = +data.gender;axios({url: "https://hmajax.itheima.net/api/settings",method: "PUT",data: {...data,creator,},}).then((res) => {// console.log(res.data);getData();});
});
6. 作业
6.1 英雄百科
<!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" /><link rel="stylesheet" href="./css/bootstrap.min.css" /><link rel="stylesheet" href="./css/index.css" /><title>英雄百科</title>
</head><body><div class="main"><img class="cover"src="https://img.crawler.qq.com/lolwebschool/0/JAutoCMS_LOLWeb_f6416138ae858f73e2ca40a11587e17f/0" /><div class="hero-container"><input type="text" class="search" placeholder="检索" /><ul class="list"><li><img src="http://game.gtimg.cn/images/lol/act/img/champion/Annie.png" class="pic" alt="" /><p>安妮</p></li></ul></div></div><div id="infoModal" class="modal" tabindex="-1"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">黑暗之女安妮</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div><div class="modal-body"><div class="info"><img src="http://game.gtimg.cn/images/lol/act/img/champion/Annie.png" class="icon img-thumbnail"alt="..." /><div class="progress-box"><div class="progress"><div class="attack progress-bar bg-success" style="width: 25%">攻击:</div></div><div class="progress"><div class="defense progress-bar bg-info" role="progressbar" style="width: 50%">防御:</div></div><div class="progress"><div class="magic progress-bar bg-warning" role="progressbar" style="width: 75%">魔法:</div></div><div class="progress"><div class="difficulty progress-bar bg-danger" role="progressbar" style="width: 100%">难度:</div></div></div></div><p>拥有危险夺命的能力,却长着一幅小大人儿的可爱模样,这就是掌握深不可测占火魔法的女孩——安妮。安妮生活在诺克萨斯北边的山脚下,但即便是在这种地方,她也依然是魔法师中的异类。她与火焰的紧密关系与生俱来——最初那些火焰是伴随着喜怒无常的冲动情绪出现的,后来她学会了如何掌握这些“好玩的小把戏”。其中,安妮最喜欢的就是她召唤亲爱的泰迪熊提伯斯——那头狂野的守护火兽。如今安妮已经迷失在了永恒的天真里,她在黑暗森林中游荡,寻觅着能陪自己玩耍的人。</p></div></div></div></div>
</body>
<script src="./lib/axios.js"></script>
<script src="./lib/bootstrap.min.js"></script>
<script>/*需求如下:渲染英雄列表数据搜索英雄渲染英雄详情数据*/// 1. 渲染英雄列表数据axios({url: 'https://hmajax.itheima.net/api/lol/search',}).then(res => {console.log(res.data.data)render(res.data.data)})function render(data) {let str = data.map(item => {return `<li><img src=${item.icon} class="pic" alt="" data-id="${item.heroId}" /><p>${item.title}</p></li>`}).join('')document.querySelector('.list').innerHTML = str}// 2. 搜索英雄const search = document.querySelector('.search')search.addEventListener('keyup', function (e) {console.log(e)if (e.code === 'Enter') {// if (e.key === 'Enter') {console.log(1)const q = search.valueaxios({url: 'https://hmajax.itheima.net/api/lol/search',params: {q,}}).then(res => {render(res.data.data)})}})// 3. 渲染英雄详情数据 事件委托const modal = new bootstrap.Modal(document.querySelector('.modal'))document.querySelector('.list').addEventListener('click', function (e) {console.log(e)if (e.target.classList.contains('pic')) {// console.log(11)// console.log()const id = e.target.dataset.idaxios({url: 'https://hmajax.itheima.net/api/lol/info',params: {id}}).then(res => {console.log(res.data.data.hero)const { name, title, icon, shortBio, attack, defense, magic, difficulty } = res.data.data.herodocument.querySelector('.modal-content').innerHTML = `<div class="modal-header"><h5 class="modal-title">${name + title}</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div><div class="modal-body"><div class="info"><img src=${icon} class="icon img-thumbnail"alt="..." /><div class="progress-box"><div class="progress"><div class="attack progress-bar bg-success" style="width: ${attack / 10 * 100 + '%'}">攻击:</div></div><div class="progress"><div class="defense progress-bar bg-info" role="progressbar" style="width: ${defense / 10 * 100 + '%'}">防御:</div></div><div class="progress"><div class="magic progress-bar bg-warning" role="progressbar" style="width: ${magic / 10 * 100 + '%'}">魔法:</div></div><div class="progress"><div class="difficulty progress-bar bg-danger" role="progressbar" style="width: ${difficulty / 10 * 100 + '%'}">难度:</div></div></div></div><p>${shortBio}</p></div>`modal.show()})}})
</script></html>
6.2 必要商城-分类
<script>/*需求如下:页面默认展示所有一级分类数据点击一级分类切换,展示下属二级分类数据点击二级分类分类,展示下属三级分类数据*/const ulOne = document.querySelector('#one')/* function render(data) {let str = data.map(item => {return `<li class="item">${item.firstName}</li>`}).join('')ulOne.innerHTML = str} */// 1. 页面默认展示所有一级分类数据axios({url: 'https://hmajax.itheima.net/api-s/categoryfirst',}).then(res => {// console.log(res.data.list)let str = res.data.list.map(item => {// console.log(item.firstId)return `<li class="item" data-id="${item.firstId}">${item.firstName}</li>`}).join('')ulOne.innerHTML = str})// 2. 点击一级分类切换,展示下属二级分类数据const ulTwo = document.querySelector('#two')ulOne.addEventListener('click', function (e) {if (e.target.classList.contains('item')) {// console.log(e.target.dataset.id)// console.log(e)const firstId = e.target.dataset.idaxios({url: 'https://hmajax.itheima.net/api-s/categorySecond',params: {firstId,}}).then(res => {// console.log(res.data.list)let str = res.data.list.map(item => {return `<li class="item" data-id="${item.secondId}">${item.secondName}</li>`}).join('')ulTwo.innerHTML = str})}})// 3. 点击二级分类分类,展示下属三级分类数据const ulThree = document.querySelector('#three')ulTwo.addEventListener('click', function (e) {if (e.target.classList.contains('item')) {const secondId = e.target.dataset.idaxios({url: 'https://hmajax.itheima.net/api-s/categoryThird',params: {secondId,}}).then(res => {// console.log(res.data.list)let str = res.data.list.map(item => {return `<li class="item">${item.thiredName}</li>`}).join('')ulThree.innerHTML = str})}})</script>