共计 3166 个字符,预计需要花费 8 分钟才能阅读完成。
背景
最近做了图片上传和预览的性能,总结了原生 js 获取本地上传图片的 base64 编码并读取图片的宽和高的实现办法。
实现
1、成果
假如咱们的文件上传页面构造是这样的:
当咱们点击附件信息处的加号时就会调出图片上传,抉择一张图片进行上传。
图片上传胜利
鼠标悬浮在图片上将呈现放大和删除的图标。
点击放大镜咱们能够预览图片
2、页面标签:
咱们精简一下页面,只留下图片上传及预览所用到的页面标签,如下:
<!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> | |
</head> | |
<body> | |
<!-- 文件上传框区域, 咱们只承受图片类型的文件上传 暗藏域 --> | |
<input class="ivu-input-file" type="file" accept="image/gif,image/jpeg,image/jpg,image/png" style="display:none"/> | |
<!-- 上传文件展现区域 --> | |
<div class="ivu-img-wrapper"> | |
<!-- 这里是图片容器 --> | |
<-- 上传后展现的图片 动态创建标签 --> | |
<img class="ivu-file-img" src="${src}"></img> | |
<-- 鼠标悬浮呈现预览和删除按钮图标 动态创建标签 --> | |
<div class="ivu-file-pop"> | |
<img src="${enlarge}" id="ivu-enlarge-${order}"></img> | |
<img src="${cut}" id="ivu-cut-${order}"></img> | |
</div> | |
<!-- 点击该区域进行图片上传 --> | |
<div class="ivu-annex"> | |
+ | |
</div> | |
</div> | |
<-- 遮罩层 图片预览显示 --> | |
<div class="ivu-pop"> | |
<div class="ivu-pop-wrapper"> | |
<img class="ivu-pop-close" src="${closePop}"> | |
</img> | |
<img class="ivu-pop-img" src="${down}"></img> | |
</div> | |
</div> | |
</body> | |
<script> | |
</script> | |
</html> |
3、js 代码
咱们用原生 js 来实现第一个步骤所形容的成果。
以下代码将增加到上个步骤的 <script> 标签中
首先咱们给加号绑定事件
// 获取加号元素 | |
let annex = document.querySelector(".ivu-annex"); | |
// 绑定点击事件 | |
annex.addEventListener("click", function() { | |
// 拿到暗藏的文件上传域 | |
let fileDomain = document.querySelector(".ivu-input-file"); | |
// 触发文件上传域事件 | |
fileDomain.click();}); |
接下来咱们来绑定文件上传域事件
// 文件上传域元素 | |
let fileInput = document.querySelector(".ivu-input-file"); | |
// 用来寄存 base64 图片的数组 | |
var fileList = []; | |
// 给文件上传域绑定 change 事件 | |
fileInput.addEventListener("change", function() { | |
// 获取寄存图片的容器 | |
let imgWrapper = document.querySelector(".ivu-img-wrapper"); | |
// 获取加号元素 | |
let operate = document.querySelector(".ivu-annex"); | |
// 获取上传的图片 | |
let file = fileInput.files[0]; | |
// 筹备读取图片 | |
if (window.FileReader && file) { | |
// 调用图片读取办法 | |
var reader = new FileReader(); | |
// 读取图片 | |
reader.readAsDataURL(file); | |
// 监听图片读取进度 | |
reader.onloadend = function(e) { | |
// 读取胜利,拿到 base64 编码 | |
let imgBase64 = e.target.result; | |
// 接下来动态创建标签 跟上个步骤页面标签备注中 动态创建标签的地位相响应,以下这些动作均为应用原生 js 创立了动静的 img 标签以及动态创建了放大和删除的遮罩层。可依据本人的我的项目及业务需要自行调整。也能够跳过该局部,间接看图片预览。let order = fileList.length; | |
let div = document.createElement("div"); | |
div.className = `ivu-file-annex${order}`; | |
div.innerHTML = createImg(imgBase64, order); | |
fileList.push(imgBase64); | |
imgWrapper.insertBefore(div, operate); | |
// 在这里初始化下图片预览事件 | |
previewImg(imgBase64, order) | |
}; | |
} |
通过以上步骤咱们曾经拿到了 base64 的图片流,接下来咱们来实现预览性能。
function previewImg (imgBase64, order){ | |
// 获取以后图片对应的放大镜元素 | |
let previewImg = document.querySelector(`#ivu-enlarge-${order}`); | |
// 给放大镜绑定事件 | |
previewImg.addEventListener("click", function() { | |
// 申明异步解决 promise 对象 | |
new Promise(function(resolve, reject) { | |
// 创立一个标签用来加载图片 | |
const image = document.createElement("img"); | |
image.src = imgBase64 | |
// 待图片加载实现读取图片的实在宽高。image.addEventListener("load", function(e) { | |
resolve({ | |
imgWidth: e.target.width, | |
imgHeight: e.target.height, | |
}); | |
}) | |
.then(({imgWidth,imgHeight})=>{ | |
// 遮罩层 | |
let pop = document.querySelector(".ivu-pop"); | |
// 预览图片容器 | |
let wrapper = document.querySelector(".ivu-pop-wrapper"); | |
// 预览图片 | |
let imgPop = document.querySelector(".ivu-pop-img"); | |
//base64 放入预览图片 img 标签 src | |
imgPop.src = imgBase64; | |
// 设置容器大小为图片的实在大小 | |
wrapper.style.width = `${imgWidth}px`; | |
wrapper.style.height = `${imgHeight}px`; | |
// 展现遮罩层 预览图片 | |
pop.style.display = "block"; | |
}) | |
}); | |
} |
总结
以上就是应用原生 js 获取本地上传的图片转成 base64 流并读取到图片的实在宽高进行预览的例子,该文解说了次要思路,具体实现细节还波及到一些款式,大家依照这个思路联合本人的业务需要进行实现。如有疑难,欢送评论区里进行探讨!!
正文完
发表至: javascript
2022-05-31