图片上传的优化--瞬间展示图片。

126 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情”

传统图片上传

我们在做图片上传的时候,流程是

graph TD

圆角([选择图片]) ---> 圆形([调用上传接口]) ---> store([返回上传后的http:...img 图片]) ---> 展示([用图片的的url连接下载展示图片])

思考:既然图片本地的为什么要通过上传下载后才展示图片呢。

优化后图片上传

graph TD

圆角([选择图片]) ---> 展示([展示图片]) ---> 上传([最后提交再上传])
展示([展示图片]) ---> 上传1([后台静默上传])

实现

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>上传</title>
</head>

<body>
   // input type file(不是files)表示的就是上传。
    <input type="file" accept="image/*">
    <img src="" alt="" id="preview" />
</body>
<script type="text/javascript" src="./index.js"></script>

</html>

展示出来的效果,input的type是file所以input就是选择文件的按钮形状。

image.png

我们要做的是

  • 获取用户选的文件 监听input的change事件即选择图片的回调。
 input.addEventListener('change', e => {
    console.log(e.target.files[0])
})

或者

input.onchange = function () {
    console.log(this.files[0])
}
  • 读取图片base64
const reader = new FileReader();
reader.readAsDataURL(e.target.files[0])
  • 展示base64图片
    reader.onload = function (event) {
        preview.src = event.target.result
     }

最终完整代码

const input = document.querySelector('input')
input.addEventListener('change', e => {
    console.log(e.target.files[0])
    const reader = new FileReader();
    reader.readAsDataURL(e.target.files[0])
    reader.onload = function (event) {
        console.log(event)
        preview.src = event.target.result
    }
})

最终选择图片后的效果。

image.png

扩展

实际开发中UI定制

隐藏input, 代码激活input的click事件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>上传</title>
</head>

<body>
    <!-- <link rel="stylesheet" MIME-type="text/css" href="./index.js" /> -->
    <input type="file" accept="image/*" style="display: none;">
    <img src="" alt="" id="preview" style="width: 100px;" />
    <button>自定义上传的按钮,也可以是图片</button>
</body>
<script type="text/javascript" src="./index.js"></script>

</html>

js增加如下代码

const button = document.querySelector('button')
button.onclick = function () {
    input.click()
}

最终展示效果

image.png

为什么id可以直接获取dom对象

 preview.src = event.target.result

为什么不是

const preview = document.getElementById('preview')
preview.src = event.target.result`

HTML5规范文档中:如果一个元素符合下面两条规则中的任一条,则window对象中必须要有与之对应的一个属性,属性值就是这个对象.

  1. 如果一个元素拥有ID属性,那么ID属性的属性值就会成为window对象的属性名.
  2. 如果一个元素拥有name属性,那么name属性的属性值就会成为window对象的属性名.但这个元素的标签名必须是: a, applet, area, embed, form, frame, frameset, iframe, img, object,其中的一个.

什么是base64

格式 data: [MIME]; base64, 二进制转换成base64编码后的数据

MIME: multipart/form-data application/xml text/javascript

"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAA......."

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情”