<!--
请按要求书写一个图片上传的弹窗组件,弹窗的样式要求如下:
1、样式要求
(1)宽: 668px, 高: 608px, 圆角5px, 边框1px solid #ccc
(2)弹窗垂直居中, 左右居中
(3)标题栏高 :50px , 右边的x不能使用图片,请使用css3画出, 标题文字颜色:红色
(4)列表元素的高:110px , 宽:110px, 边框 1px solid #ccc
(5)中间“添加”按钮的图片地址:https://p1.pstatp.com/large/3ecd0004b6bdeff4c48d
整体样式效果如下图所示:
2、功能要求
(1)点击“添加”按钮弹出文件选择框, 选择图片(要求只能选择png、jpeg、jpg三种图片)
(2)选择图片后列表增加一张图片缩略图展示(此时图片未上传到服务器)
(3)点击上传按钮将当前选择的图片上传到图片服务器(只要求上传当前选择的一张图片,如能实现多个同时上传更佳),上传的图片的接口地址: https://mp.toutiao.com/profile_v2/
接口说明:接口只接收并且处理二进制文件。
请编码实现。
(注:不支持本地IDE)
-->
<!DOCTYPE html>
<html>
<head>
<title>弹窗组件练习</title>
<style>
.popup {
position: absolute;
/* 绝对地址,
position: fixed;
在有滚动条的情况下,fixed定位不会随滚动条移动而移动,而absolute则会随滚动条移动。
可以这么理解,fixed:固定在当前window不动, absolute:会随参照对象元素的高度和宽度变化而变化
一般fixed用在遮盖层和固定在页面某个位置,如固定在顶端的菜单栏,又如弹出提示框居中显示
*/
width: 668px;
height: 608px;
border: 1px solid #ccc;
border-radius: 5px;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
.popup>.title {
position: relative;
height: 50px;
box-sizing: border-box;
/*
盒子模型是指:外边距(margin)+ border(边框) + 内边距(padding)+ content(内容)
加了box-sizing:border-box属性,padding和border的值就不会在影响元素的宽高,
相当于把padding和border的值都算在content里,盒子模型会自动根据padding和border的值来调整content的值,
就不需要手动调整
*/
color: red;
margin: 0;
font-size: 16px;
border-bottom: 1px solid #ccc;
padding-left: 20px;
line-height: 50px;
}
.popup>.title>.text {
display:inline-block;
/* 内联块元素
inline-block的特点是结合inline和block两种属性的特定,
可以设置width和height,并且元素保持行内排列的特性,基于这一点,
所有行内排列并且可以设置大小的场景都是我们可以考虑使用inline-block的应用场景
网页头部的菜单就是典型的横向排列并且需要设置大小的应用,在inline-block之前,
实现菜单基本都是用float属性来实现,float属性会造成高度塌陷,
需要清除浮动等问题,使用inline-block实现就不需要在意这样的问题
inline-block布局 vs 浮动float布局
不同之处:
display:inline-block ::::元素不会脱离文本流,但存在间隙问题,需要对父元素添加font-size:0;
float: left;::::会使得元素脱离文本流,且还有父元素高度坍塌的效果,所以要闭合浮动overflow:hidden;
*/
height: 49px;
border-bottom: 2px solid red;
padding: 0 5px;
}
.popup>.title>.close {
position: absolute;
display: block;
right: 20px;
width: 20px;
height: 20px;
top: 15px;
cursor: pointer;
/* 网页浏览时用户鼠标指针的样式,手型 */
}
.popup>.title>.close::after {
/* 这个是叉叉的\ */
content: ' ';
position: absolute;
display: block;
width: 100%;
height: 1px;
background-color: rgb(83, 113, 201);
top: 10px;
transform: rotate(45deg);
}
.popup>.title>.close::before {
/* 这个是叉叉的/ */
content: ' ';
position: absolute;
display: block;
width: 100%;
height: 1px;
background-color: rgb(202, 31, 31);
top: 10px;
transform: rotate(-45deg);
}
.popup>.content {
display: flex;
flex-wrap: wrap;
/* 让弹性盒元素在必要的时候拆行 */
}
.popup>.content>img,
.popup>.content>.label {
/* 这个写法就是把 popup>.content>img和.popup>.content>.label
一样的样式写在一起*/
width: 110px;
height: 110px;
border: 1px solid #ccc;
margin: 20px 10px 0 20px;
}
.popup>.content>.label {
cursor: pointer;
}
.popup>.content>.label>img {
width: 100%;
height: 100%;
}
.popup>.footer {
display: flex;
width: 100%;
height: 70px;
position: absolute;
bottom: 0;
left: 0;
right: 0;
border-top: 1px solid #ccc;
justify-content: space-around;
/* 在弹性盒对象的 <div> 元素中的各项周围留有空白 */
align-items: center;
/* 居中对齐弹性盒的各项 <div> 元素 */
}
.popup>.footer>.start-upload,
.popup>.footer>.cancel-upload {
width: 70px;
height: 30px;
border: none;
border-radius: 5px;
outline: none;
cursor: pointer;
}
.popup>.footer>.start-upload {
background-color: red;
color: aliceblue;
}
</style>
</head>
<body>
<!-- 弹出层盒子 -->
<div class="popup">
<h1 class="title">
<span class="text">上传图片</span>
<span class="close"></span>
</h1>
<div class="content">
<!-- const thump = document.getElementsByClassName('thump')[0]指的是这里,
必须带上[0],否则找不到 -->
<img src="aa.jpg" alt="" class="thump">
<label for="upload-file" class="label">
<img src="aaa.jpeg" alt="">
<!-- 当HTML元素本身的物件无法被渲染时,就显示alt(替换)文字作为一种补救措施
const inputFile = document.getElementById('upload-file')指向的就是这里
-->
<input style="display: none;" id="upload-file" type="file" accept=".png,.jpeg,.jpg" class="upload-file">
</label>
</div>
<div class="footer">
<button class="start-upload">上传</button>
<button class="cancel-upload">取消</button>
</div>
</div>
<script>
//前面!\,\; 为了分隔上方可能存在的方法
!(function () {
const inputFile = document.getElementById('upload-file')
const thump = document.getElementsByClassName('thump')[0]
let file = null
inputFile.addEventListener('change', function (event) {
file = this.files[0]
const reader = new FileReader()
let base64 = ''
reader.readAsDataURL(file)
reader.onload = function (event) {
base64 = reader.result
thump.src = base64
}
})
// https://mp.toutiao.com/profile_v2/
const uploadBtn = document.getElementsByClassName('start-upload')[0]
uploadBtn.addEventListener('click', function () {
if (!file) return
const xhr = new XMLHttpRequest()
// xhr.setRequestHeader()
xhr.open('post', 'https://mp.toutiao.com/profile_v2/')
xhr.onload = function () {
console.log(xhr.response)
}
const form = new FormData()
form.append('file', file)
xhr.send(form)
})
})()
//自执行函数,匿名
</script>
</body>
</html>