forEach渲染案例
- 图解
- 代码
// 1. 声明一个字符串变量
let str = ''
// 2. 遍历数据
goodsList.forEach(item => {
// console.log(item) // 可以得到每一个数组元素 对象 {id: '4001172'}
// const {id} = item 对象解构
const { name, price, picture } = item
str += `
<div class="item">
<img src=${picture} alt="">
<p class="name">${name}</p>
<p class="price">${price}</p>
</div>
`
})
// 3.生成的 字符串 添加给 list
document.querySelector('.list').innerHTML = str
- 解析
forEach没有返回值,适用于遍历数组
filter价格筛选案例
- 图解
- 代码
// 1. 渲染函数 封装
function render(arr) {
// 声明空字符串
let str = ''
// 遍历数组
arr.forEach(item => {
// 解构
const { name, picture, price } = item
str += `
<div class="item">
<img src=${picture} alt="">
<p class="name">${name}</p>
<p class="price">${price}</p>
</div>
`
})
// 追加给list
document.querySelector('.list').innerHTML = str
}
render(goodsList) // 页面一打开就需要渲染
// 2. 过滤筛选
document.querySelector('.filter').addEventListener('click', e => {
// e.target.dataset.index e.target.tagName
const { tagName, dataset } = e.target
// 判断
if (tagName === 'A') {
// console.log(11)
// arr 返回的新数组
let arr = goodsList
if (dataset.index === '1') {
arr = goodsList.filter(item => item.price > 0 && item.price <= 100)
} else if (dataset.index === '2') {
arr = goodsList.filter(item => item.price >= 100 && item.price <= 300)
} else if (dataset.index === '3') {
arr = goodsList.filter(item => item.price >= 300)
}
// 渲染函数
render(arr)
}
})
</script>
购物车案例
- 图解
- 代码
<!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>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.list {
width: 990px;
margin: 100px auto 0;
}
.item {
padding: 15px;
transition: all .5s;
display: flex;
border-top: 1px solid #e4e4e4;
}
.item:nth-child(4n) {
margin-left: 0;
}
.item:hover {
cursor: pointer;
background-color: #f5f5f5;
}
.item img {
width: 80px;
height: 80px;
margin-right: 10px;
}
.item .name {
font-size: 18px;
margin-right: 10px;
color: #333;
flex: 2;
}
.item .name .tag {
display: block;
padding: 2px;
font-size: 12px;
color: #999;
}
.item .price,
.item .sub-total {
font-size: 18px;
color: firebrick;
flex: 1;
}
.item .price::before,
.item .sub-total::before,
.amount::before {
content: "¥";
font-size: 12px;
}
.item .spec {
flex: 2;
color: #888;
font-size: 14px;
}
.item .count {
flex: 1;
color: #aaa;
}
.total {
width: 990px;
margin: 0 auto;
display: flex;
justify-content: flex-end;
border-top: 1px solid #e4e4e4;
padding: 20px;
}
.total .amount {
font-size: 18px;
color: firebrick;
font-weight: bold;
margin-right: 50px;
}
</style>
</head>
<body>
<div class="list">
<!-- <div class="item">
<img src="https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg" alt="">
<p class="name">称心如意手摇咖啡磨豆机咖啡豆研磨机 <span class="tag">【赠品】10优惠券</span></p>
<p class="spec">白色/10寸</p>
<p class="price">289.90</p>
<p class="count">x2</p>
<p class="sub-total">579.80</p>
</div> -->
</div>
<div class="total">
<div>合计:<span class="amount">1000.00</span></div>
</div>
<script>
const goodsList = [
{
id: '4001172',
name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
price: 289.9,
picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
count: 2,
spec: { color: '白色' }
},
{
id: '4001009',
name: '竹制干泡茶盘正方形沥水茶台品茶盘',
price: 109.8,
picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
count: 3,
spec: { size: '40cm*40cm', color: '黑色' }
},
{
id: '4001874',
name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
price: 488,
picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
count: 1,
spec: { color: '青色', sum: '一大四小' }
},
{
id: '4001649',
name: '大师监制龙泉青瓷茶叶罐',
price: 139,
picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
count: 1,
spec: { size: '小号', color: '紫色' },
gift: '50g茶叶,清洗球,宝马, 奔驰'
}
]
// 1. 根据数据渲染页面
document.querySelector('.list').innerHTML = goodsList.map(item => {
// console.log(item) // 每一条对象
// 对象解构 item.price item.count
const { picture, name, count, price, spec, gift } = item
// 规格文字模块处理
const text = Object.values(spec).join('/')
// 计算小计模块 单价 * 数量 保留两位小数
// 注意精度问题,因为保留两位小数,所以乘以 100 最后除以100
const subTotal = ((price * 100 * count) / 100).toFixed(2)
// 处理赠品模块 '50g茶叶,清洗球'
const str = gift ? gift.split(',').map(item => `<span class="tag">【赠品】${item}</span> `).join('') : ''
return `
<div class="item">
<img src=${picture} alt="">
<p class="name">${name} ${str} </p>
<p class="spec">${text} </p>
<p class="price">${price.toFixed(2)}</p>
<p class="count">x${count}</p>
<p class="sub-total">${subTotal}</p>
</div>
`
}).join('')
// 3. 合计模块
const total = goodsList.reduce((prev, item) => prev + (item.price * 100 * item.count) / 100, 0)
// console.log(total)
document.querySelector('.amount').innerHTML = total.toFixed(2)
</script>
</body>
</html>
面向对象弹窗
- 图解
- 代码
<!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>
.modal {
width: 300px;
min-height: 100px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
border-radius: 4px;
position: fixed;
z-index: 999;
left: 50%;
top: 50%;
transform: translate3d(-50%, -50%, 0);
background-color: #fff;
}
.modal .header {
line-height: 40px;
padding: 0 10px;
position: relative;
font-size: 20px;
}
.modal .header i {
font-style: normal;
color: #999;
position: absolute;
right: 15px;
top: -2px;
cursor: pointer;
}
.modal .body {
text-align: center;
padding: 10px;
}
.modal .footer {
display: flex;
justify-content: flex-end;
padding: 10px;
}
.modal .footer a {
padding: 3px 8px;
background: #ccc;
text-decoration: none;
color: #fff;
border-radius: 2px;
margin-right: 10px;
font-size: 14px;
}
.modal .footer a.submit {
background-color: #369;
}
</style>
</head>
<body>
<button id="delete">删除</button>
<button id="login">登录</button>
<!-- <div class="modal">
<div class="header">温馨提示 <i>x</i></div>
<div class="body">您没有删除权限操作</div>
</div> -->
<script>
// 1. 模态框的构造函数
function Modal(title = '', message = '') {
// 公共的属性部分
this.title = title
this.message = message
// 因为盒子是公共的
// 1. 创建 一定不要忘了加 this
this.modalBox = document.createElement('div')
// 2. 添加类名
this.modalBox.className = 'modal'
// 3. 填充内容 更换数据
this.modalBox.innerHTML = `
<div class="header">${this.title} <i>x</i></div>
<div class="body">${this.message}</div>
`
// console.log(this.modalBox)
}
// 2. 打开方法 挂载 到 模态框的构造函数原型身上
Modal.prototype.open = function () {
if (!document.querySelector('.modal')) {
// 把刚才创建的盒子 modalBox 渲染到 页面中 父元素.appendChild(子元素)
document.body.appendChild(this.modalBox)
// 获取 x 调用关闭方法
this.modalBox.querySelector('i').addEventListener('click', () => {
// 箭头函数没有this 上一级作用域的this
// 这个this 指向 m
this.close()
})
}
}
// 3. 关闭方法 挂载 到 模态框的构造函数原型身上
Modal.prototype.close = function () {
document.body.removeChild(this.modalBox)
}
// 4. 按钮点击
document.querySelector('#delete').addEventListener('click', () => {
const m = new Modal('温馨提示', '您没有权限删除')
// 调用 打开方法
m.open()
})
// 5. 按钮点击
document.querySelector('#login').addEventListener('click', () => {
const m = new Modal('友情提示', '您还么有注册账号')
// 调用 打开方法
m.open()
})
</script>
</body>
</html>
视频节流缓存
- 解析
下次打开从上次播放位置继续播放
- 代码
<!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" />
<meta name="referrer" content="never" />
<title>综合案例</title>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.container {
width: 1200px;
margin: 0 auto;
}
.video video {
width: 100%;
padding: 20px 0;
}
.elevator {
position: fixed;
top: 280px;
right: 20px;
z-index: 999;
background: #fff;
border: 1px solid #e4e4e4;
width: 60px;
}
.elevator a {
display: block;
padding: 10px;
text-decoration: none;
text-align: center;
color: #999;
}
.elevator a.active {
color: #1286ff;
}
.outline {
padding-bottom: 300px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<a href="http://pip.itcast.cn">
<img src="https://pip.itcast.cn/img/logo_v3.29b9ba72.png" alt="" />
</a>
</div>
<div class="video">
<video src="https://v.itheima.net/LapADhV6.mp4" controls></video>
</div>
<div class="elevator">
<a href="javascript:;" data-ref="video">视频介绍</a>
<a href="javascript:;" data-ref="intro">课程简介</a>
<a href="javascript:;" data-ref="outline">评论列表</a>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<script>
// 1. 获取元素 要对视频进行操作
const video = document.querySelector('video')
video.ontimeupdate = _.throttle(() => {
// console.log(video.currentTime) 获得当前的视频时间
// 把当前的时间存储到本地存储
localStorage.setItem('currentTime', video.currentTime)
}, 1000)
// 打开页面触发事件,就从本地存储里面取出记录的时间, 赋值给 video.currentTime
video.onloadeddata = () => {
// console.log(111)
video.currentTime = localStorage.getItem('currentTime') || 0
}
</script>
</body>
</html>
完结~