bootstrap弹窗
官网链接:
1.通过属性控制,弹框显示或隐藏
2.通过JS控制,弹框显示或隐藏
一、图书管理(案例)
1.图书列表(渲染数据)
一 渲染图书列表
*/
// 3.3 抽取creator为变量
const creator = 'itheima1011'
// 2.4 抽取渲染图书列表的逻辑为函数
function getBooks() {
axios({
url: 'http://hmajax.itheima.net/api/books',
// 3.4 替换为变量
params: {
creator
}
}).then(res => {
console.log(res)
const htmlArr = res.data.data.map((item, index) => {
const { author, bookname, publisher, id } = item
// 2.2 在删除按钮上保存id
return `<tr>
<td>${index + 1}</td>
<td>${bookname}</td>
<td>${author}</td>
<td>${publisher}</td>
<td>
<span data-id="${id}" class="del">删除</span>
<span data-id="${id}" class="edit">编辑</span>
</td>
</tr>`
})
const htmlStr = htmlArr.join('')
document.querySelector('.list').innerHTML = htmlStr
})
}
// 2.5 默认调用一次
getBooks()
2.新增图书(新增数据)
addForm.reset()重置表单
const data = serialize(addForm, { hash: true, empty: true })表单收集
/*
三 新增图书
*/
const addModal = new bootstrap.Modal(document.querySelector('.add-modal'))
document.querySelector('.add-btn').addEventListener('click', () => {
// 3.2 收集表单数据
const addForm = document.querySelector('.add-form')
const data = serialize(addForm, { hash: true, empty: true })
console.log('data:', data)
// 3.3 提交到服务器
axios({
url: 'http://hmajax.itheima.net/api/books',
method: 'POST',
data: {...data, creator }
}).then(res => {
// console.log(res)
// 关闭弹窗
addModal.hide()
// 重置表单
addForm.reset()
// 重新获取数据
getBooks()
})
})
3.删除图书(删除数据)
/*
二 删除图书
*/
// 2.1 事件委托绑定事件
document.querySelector('.list').addEventListener('click', (e) => {
if (e.target.classList.contains('del')) {
// 2.3 获取保存在删除按钮上的id
const { id } = e.target.dataset
axios({
url: `http://hmajax.itheima.net/api/books/${id}`,
method: 'delete'
}).then(res => {
// console.log(res)
// 2.6 删除成功之后 重新获取数据并渲染
getBooks()
})
}
})
4.编辑图书(修改数据)
对象数组循环
// 四 编辑图书
const editModal = new bootstrap.Modal(document.querySelector('.edit-modal'))
document.querySelector('.list').addEventListener('click', (e) => {
if (e.target.classList.contains('edit')) {
const { id } = e.target.dataset
axios({
url: `http://hmajax.itheima.net/api/books/${id}`,
}).then(res => {
console.log(res)
// 保存图书数据
// document.querySelector('.edit-modal .bookname').value = res.data.data.bookname
// document.querySelector('.edit-modal .author').value = res.data.data.author
// document.querySelector('.edit-modal .publisher').value = res.data.data.publisher
for (const key in res.data.data) {
document.querySelector(`.edit-modal .${key}`).value = res.data.data[key]
}
editModal.show()
})
}
})
整体
// 有一个creator 数据,表示自己的账户名
const creator = 'daqiu8888'
// 获取服务器的数据渲染 -- 新增-编辑和删除都需要请求服务器最新数据渲染 → 封装函数
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 {bookname, author,publisher, id} = 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()
// 删除和编辑 → 事件委托
let id = ''
document.querySelector('.list').addEventListener('click', function(e) {
// 如果点击的是删除按钮 执行删除功能 → 按id删除 → 数据来源于服务器:向服务器发请求,删除的请求-id → 服务器执行删除 → 渲染最新数据
id = e.target.dataset.id
if (e.target.classList.contains('del')) {
// console.log(1)
// `https://hmajax.itheima.net/api/books/${id}`
axios({
url: `https://hmajax.itheima.net/api/books/${id}`,
method: 'DELETE'
}).then(res=>{
// console.log(res)
// 重新请求新数据去渲染
render()
})
}
// 编辑
if (e.target.classList.contains('edit')) {
edModal.show()
// 数据回显 → 数据都在服务器上面,要拿着id向服务器发请求,拿到最新的数据渲染到value值
axios({
url: `https://hmajax.itheima.net/api/books/${id}`
})
.then(res=>{
console.log(res)
const data = res.data.data
// 放上父选择器edit-form,新增和编辑的表单输入框名字相同,新增在上面,querySelector只找第一个
// document.querySelector('.edit-form .bookname').value = data.bookname
// document.querySelector('.edit-form .author').value = data.author
// document.querySelector('.edit-form .publisher').value = data.publisher
for (const key in data) {
// 对象名.属性名 -- 必须是真实存在的属性名
// key 是变量名 对象名[变量]
document.querySelector(`.edit-form .${key}`).value = data[key]
}
})
}
})
// 修改按钮的点击事件 → 收集用户新输入的数据 发送到服务器保存 → 渲染新数据 → 关闭弹窗
document.querySelector('.edit-btn').addEventListener('click', function() {
const data = serialize(document.querySelector('.edit-form'), {hash: true, empty: true})
axios({
url: `https://hmajax.itheima.net/api/books/${id}`, // 这里的id要和事件委托的id相同 → 把事件委托的id提到全局变量
method: 'put',
data: {
creator,
...data
}
})
.then(res => {
// console.log(res)
render()
edModal.hide()
})
})
// 定义编辑编辑的弹窗
const editModal = document.querySelector('.edit-modal')
const edModal = new bootstrap.Modal(editModal)
// 增加图书 → 添加按钮点击,弹出输入框 → 用户输入,点增加按钮,把用户输入的数据发送到服务器保存 → 发请求得到最新数据渲染
// 把增加的弹窗写到全局 → 增加完图书要隐藏弹窗
const addModal = document.querySelector('.add-modal')
const modal = new bootstrap.Modal(addModal)
document.querySelector('.plus-btn').addEventListener('click', function() {
modal.show()
})
document.querySelector('.add-btn').addEventListener('click', function() {
// 用serialize收集数据 → 检查表单输入框是否有name属性
// serialize(收集表单,{hash:true,empty:true})
const data = serialize(document.querySelector('.add-form'), {hash:true,empty:true})
console.log(data)
axios({
url: 'https://hmajax.itheima.net/api/books',
method: 'post',
data: {
creator,
// 解构data常量
...data
}
}).then(res=>{
// console.log(res)
render()
modal.hide()
// document.querySelector('.bookname').value = ''
// document.querySelector('.author').value = ''
// document.querySelector('.publisher').value = ''
// console.log(Object.keys(data)) [bookname, author, publisher]
Object.keys(data).forEach(key => {
document.querySelector(`.${key}`).value = ''
})
})
})
二、图片上传(知识点)
<!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>
/**
* 图片上传
* 1. 选择图片
* 2. FormData对象
* 3. 调用上传接口
* */
document.querySelector('.upload').addEventListener('change', function() {
console.log(this.files[0])
const data = new FormData()
// 往data对象里面新增数据
// data.append(key与接口参数名相同, 图片相关信息)
data.append('img', this.files[0])
// console.log(data)
axios({
url: 'https://hmajax.itheima.net/api/uploadimg',
method: 'POST',
data
}).then(res =>{
console.log(res.data.data.url)
document.querySelector('.img').src = res.data.data.url
})
})
</script>
</body>
</html>
三、网站换肤(案例)
// 给input标签skin注册change事件,上传图片,得到图片的地址,再设置给body标签作为背景图
document.querySelector('#skin').addEventListener('change', function() {
// console.log(this.files[0])
const data = new FormData()
data.append('img', this.files[0])
axios({
url: 'https://hmajax.itheima.net/api/uploadimg',
method: 'post',
data
}).then(res => {
// console.log(res.data.data.url)
// document.body.style.backgroundImage = `url(${res.data.data.url})`
// // 先保存到localstorage,背景图路径从localstorage取
localStorage.setItem('url', res.data.data.url)
document.body.style.backgroundImage = `url(${localStorage.getItem('url')})`
})
})
// 如果第一次打开 localstorage没有URL会报错,如果没有 取空字符串
document.body.style.backgroundImage = `url(${localStorage.getItem('url') || ''})`
四、个人设置(案例)
需求
信息渲染
修改头像
修改信息
const creator = 'daqiu'
// 头像上传 → 修改img的src是在线url
document.querySelector('#upload').addEventListener('change', function() {
// 组合数据 → 图片 和 creator
const data = new FormData()
data.append('avatar', this.files[0])
data.append('creator', creator)
// 发axios请求
axios({
url: 'https://hmajax.itheima.net/api/avatar',
method: 'put',
data
}).then(res =>{
// console.log(res.data.data.avatar)
document.querySelector('.avatar').src = res.data.data.avatar
})
})
// 默认获取个人信息并渲染
function render() {
axios({
url: 'https://hmajax.itheima.net/api/settings',
params: {
creator
}
}).then(res =>{
// console.log(res)
// 考虑将来用户输入多,不能一个个的更改 → 按key遍历 → 如果key==avatar 找到img标签换src属性值
// console.log(Object.keys(res.data.data)) // ['avatar', 'nickname', 'email', 'desc', 'gender']
Object.keys(res.data.data).forEach(key =>{
if (key == 'avatar') {
// document.querySelector('.avatar').src = res.data.data.avatar
document.querySelector('.avatar').src = res.data.data[key]
} else if (key == 'gender') {
// 性别 → 在两个radio里面选出一个设置checked属性值为true → 性别得到的是数字0和1
// 把数字0和1当做索引从两个标签中找一个 设置 checked属性值
const gender = res.data.data.gender
const genders = document.querySelectorAll('.gender')
genders[gender].checked = true
} else {
document.querySelector(`.${key}`).value = res.data.data[key]
}
})
})
}
render()
document.querySelector('.submit').addEventListener('click', function() {
// 收集用户输入的数据发送到后台
const data = serialize(document.querySelector('.user-form'), {hash: true, empty: true})
// 接口要求的gender值是整数,但收集到的value值是字符串类型
data.gender = +data.gender
axios({
url: 'https://hmajax.itheima.net/api/settings',
method: 'put',
data: {
creator,
...data
}
})
.then(res=>{
console.log(res)
render()
})
})
五、英雄百科(例)
1.渲染英雄列表数据,2搜索英雄,3.渲染英雄详情数据
<!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>
/**
*渲染英雄列表数据
*搜索英雄
*渲染英雄详情数据
*
*/
// 渲染列表
function render() {
axios({
url: 'https://hmajax.itheima.net/api/lol/search',
}).then(res => {
// console.log(res.data)
document.querySelector('.list').innerHTML = res.data.data.map(function(el, index) {
return `
<li>
<img src="${el.icon}" class="pic" alt="" />
<p>${el.title}</p>
</li>
`
}).join('')
})
}
render()
// 搜索英雄
const search = document.querySelector('.search')
search.addEventListener('keyup', function(e) {
if (search.value.trim() == '') {
return alert('内容不能为空')
}
if (e.key !== 'Enter') {
return
}
axios({
url: 'https://hmajax.itheima.net/api/lol/search',
params: {
q: this.value.trim(),
},
}).then(function(res) {
if (res.data.code != 400) {
document.querySelector('.list').innerHTML = res.data.data.map((v) => {
return `
<li class="item">
<img data-id='${v.heroId}' src="${v.icon}" class="pic" alt="" />
<p>${v.title}</p>
</li>`
}).join('')
} else {
alert(res.data.msg)
}
})
})
// 渲染英雄详情数据
// 功能3:渲染英雄详情数据
// 3.1 初始化模态框
const modal = new bootstrap.Modal(document.querySelector('#infoModal'))
// 3.2 由于列表是动态生成的,所以采取事件委托来将click事件委托给list父元素
document.querySelector('.list').addEventListener('click', function(e) {
// 3.3 判断点击的元素是否包含pic类名(图片)
if (e.target.classList.contains('pic')) {
// 3.4 axios 发送请求获取指定英雄数据
axios({
url: 'https://hmajax.itheima.net/api/lol/info',
method: 'get',
params: {
// 3.5 通过params 来携带英雄id
id: e.target.dataset.id,
},
}).then((res) => {
// 3.6 获取到服务器响应的数据,并设置到模态框中的对应部分
const hero = res.data.data.hero
document.querySelector('.modal-title').innerHTML = hero.name + hero.title
document.querySelector('.icon').src = hero.icon
document.querySelector('.attack').style.width = (hero.attack / 10) * 100 + '%'
document.querySelector('.defense').style.width = (hero.defense / 10) * 100 + '%'
document.querySelector('.magic').style.width = (hero.magic / 10) * 100 + '%'
document.querySelector('.difficulty').style.width = (hero.difficulty / 10) * 100 + '%'
// 3.7 当设置好模态框之后,显示模态框
modal.show()
})
}
})
</script>
</html>
六、分类商品(例)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="renderer" content="webkit" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<title>必要商城_大牌品质 工厂价格</title>
<link href="http://static.biyao.com/pc/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<link href="./lib/common.css" rel="stylesheet" type="text/css" />
<link href="./lib/new.main.css" rel="stylesheet" type="text/css" />
<link href="./lib/elementUI.css" rel="stylesheet" type="text/css" />
<link href="./lib/global.css" rel="stylesheet" type="text/css" />
<link href="./lib/iprHeader.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" type="text/css" href="./lib/new.category.css" />
</head>
<body id="pagebody">
<div class="header header-index"></div>
<!-- 导航栏 -->
<div class="nav nav-index">
<div class="clearfix">
<a href="http://www.biyao.com/home/index.html" class="nav-logo">
<img src="./lib/logo.png" height="51" />
</a>
<div class="nav-category">
<p>
<span>全部分类</span>
<i></i>
</p>
<div>
<ul class="nav-list">
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=621">
咖啡
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=627">
饮食
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=691">
正餐
</a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=279">
男装
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=294">
女装
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=35">
鞋靴
</a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=122">
眼镜
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=339">
内衣配饰
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=39">
运动
</a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=119">
美妆
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=724">
个护
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=391">
母婴
</a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=652">
生鲜直供
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=51">
餐厨
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=334">
电器
</a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=153">
箱包
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=223">
数码办公
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=429">
汽配
</a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=355">
家纺
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=10">
家具
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=369">
家装
</a>
</p>
</li>
<li class="nav-main">
<p>
<a href="http://www.biyao.com/classify/category.html?categoryId=546">
健康保健
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=685">
宠物
</a>
<span>/</span>
<a href="http://www.biyao.com/classify/category.html?categoryId=816">
礼品
</a>
</p>
</li>
</ul>
</div>
</div>
<div class="nav-search">
<p>
<input type="text" id="searchInput" placeholder="请输入要搜索的商品" />
<span id="searchBtn"></span>
</p>
<ul>
<li>电动牙刷</li>
<li>男士内裤</li>
<li>防晒霜</li>
<li>防晒</li>
<li>防晒衣女</li>
<li>眼镜近视女</li>
<li>洗发水</li>
<li>面膜</li>
<li>凉席</li>
<li>沐浴露</li>
</ul>
</div>
<div class="nav-tab">
<ul>
<li><a href="http://www.biyao.com/home/index.html">首页</a></li>
<li>
<a href="http://www.biyao.com/classify/newProduct.html">
每日上新
</a>
</li>
<li class="border-l"></li>
<li class="nav-tab-last">
<div class="hover_text">
了解必要
<div class="hover_code gzh">
<span>
关注必要微信公众号
<br />
了解你想了解的一切
<br />
小必姐在此发福利哦
</span>
</div>
</div>
</li>
<li class="nav-tab-last" id="appDownload">下载必要APP</li>
<li class="border-l"></li>
<li class="nav-tab-last">
<div class="hover_text">
我的必要
<div class="hover_code app">
<span>
扫码下载必要app
<br />
手机用户独享海量权益
</span>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<!-- 分类栏 -->
<div class="cateBread">
<span>一级分类:</span>
<ul id="one">
<li class="item">示例</li>
</ul>
</div>
<div class="cateBread">
<span>二级分类:</span>
<ul id="two">
<li class="item">休食</li>
</ul>
</div>
<div class="cateBread">
<span>三级分类:</span>
<ul id="three">
<li class="item">零食</li>
</ul>
</div>
<!-- <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> -->
<script src="https://cdn.staticfile.org/axios/1.6.2/axios.min.js"></script>
<!-- <script src="./js/axios.js"></script> -->
<script>
// 一级标题
const goods1 = document.querySelector('#one')
axios({
url: 'https://hmajax.itheima.net/api-s/categoryfirst',
}).then((res) => {
//console.log(res)
goods1.innerHTML = res.data.list.map(items => {
// data-id="${items.firstId}为了二级标题点击准备的id标识
return `
<li data-id="${items.firstId}" class="item">${items.firstName}</li>
`
}).join('')
})
// 二级标题
const goods2 = document.querySelector('#two')
goods1.addEventListener('click', function(e) {
console.log(`biao`, e)
if (Object.keys(e.target.dataset).length != 0) {
// if (e.target.classList.contains('item')) {
let firstId = e.target.dataset.id
console.log(`aaaaa`, firstId)
axios({
url: 'https://hmajax.itheima.net/api-s/categorySecond',
params: {
firstId: firstId,
}
}).then((res) => {
console.log(res)
goods2.innerHTML = res.data.list.map((items) => {
return `
<li data-id="${items.secondId}" class="item">${items.secondName}</li>
`
}).join('')
})
}
})
// 三级标题
goods2.addEventListener('click', function(e) {
console.log(e)
if (Object.keys(e.target.dataset).length != 0) {
// if (e.target.classList.contains('item')) {
let id = e.target.dataset.id
console.log(222)
axios({
url: 'https://hmajax.itheima.net/api-s/categoryThird',
params: {
secondId: id,
}
}).then(res => {
console.log(`1234567`, res)
document.querySelector('#three').innerHTML = res.data.list.map(items => {
return `
<li class="item">${items.thiredName}</li>
`
}).join('')
})
}
})
</script>
</body>
</html>