原文地址:http://zhangyiheng.com/blog/articles/img_preview.html
本文主要介绍如何通过拖拽方式在浏览器端实现图片预览,并生成图片的Base64编码。 工具链接:图片转Base64。
首先介绍一下FileReader, FileReader对象允许浏览器使用File或Blob对象异步读取存储在用户计算机上的文件(或数据缓冲区)的内容。
有了FileReader就不需要先把文件发送到服务器端,然后再返回到浏览器端显示这种模式了,可以直接在浏览器端读取文件并显示。
DND获取文件
通过对DragAndDrop事件的监听获取文件。
z.event.on(listDiv, "dragenter", this.preventAndStop, this); z.event.on(listDiv, "dragover", this.preventAndStop, this); z.event.on(listDiv, "drop", this.handleDrop, this);
加dragenter和dragover监听主要是防止默认拖拽行为的发生,可以防止浏览器将当前页面变成浏览拖拽进来的图片内容。
在drop事件监听中,可以通过dataTransfer获取拖拽到当前区域的文件列表。
var dt = evt.dataTransfer; var files = dt.files; this.readFiles(files);
FileReader读取文件
通过FileReader对象读取文件, 因为FileReader读取文件是异步操作,所以通过onload事件回调来获取读取到的文件内容。
var img = z.dom.create("img", "item"); var reader = new FileReader(); reader.onload = function (e) { img.src = e.target.result; } reader.readAsDataURL(file);
这样用户计算机中的图片文件,就可以在浏览器中预览看到了。
在此通过文件的type做了一些过滤,只读取图片类型的文件,具体实现请参考完成代码。
生成Base64
FileReader读取到的内容,其实就是文件的Base64编码内容,可以直接通过img.src来访问。
完整代码
/** * Created by taozh on 2017/11/22. */ var ToBase64 = { init: function () { this.initController(); }, initController: function () { var listDiv = z.dom.get("#listDiv"); z.event.on(listDiv, "dragenter", this.preventAndStop, this); z.event.on(listDiv, "dragover", this.preventAndStop, this); z.event.on(listDiv, "drop", this.handleDrop, this); z.event.on(listDiv, "click", this.handleClick, this); }, preventAndStop: function (evt) { evt.stopPropagation(); evt.preventDefault(); }, handleDrop: function (evt) { this.preventAndStop(evt); var dt = evt.dataTransfer; var files = dt.files; this.readFiles(files); }, readFiles: function (files) { var len = files.length; for (var i = 0; i < len; i++) { var file = files[i]; var imageType = /image.*/; if (!file.type.match(imageType)) { continue; } var img = this.addImage(file); if (i === 0) { this.setCurrent(img); } } }, addImage: function (file) { var that = this; var img = z.dom.create("img", "item"); img.file = file; z.dom.attr(img,"title",file.name); z.dom.css(img, "display", "none"); var span = z.dom.create("span"); z.dom.get("#listDiv").appendChild(img); var reader = new FileReader(); reader.onerror = function (stuff) { console.log("error", stuff); console.log(stuff.getMessage()); }; reader.onload = function (e) { img.src = e.target.result; z.util.callLater(function () { var naturalHeight = img.naturalHeight; var naturalWidth = img.naturalWidth; if (naturalHeight > 0 && naturalWidth > 0) { var m = Math.max(naturalWidth, naturalHeight) / 110; z.dom.css(img, { width: naturalWidth / m + "px", height: naturalHeight / m + "px" }) } z.dom.css(img, "display", "inline"); if (that.__currentImg === img) { z.dom.val("#dataPre", img.src); img.scrollIntoView(); } }, 200); }; reader.readAsDataURL(file); return img; }, setCurrent: function (img) { if (this.__currentImg === img) { return; } if (this.__currentImg) { z.dom.removeClass(this.__currentImg, "active"); z.dom.val("#dataPre", ""); } this.__currentImg = img; if (img) { z.dom.cls(img, "active"); z.dom.val("#dataPre", img.src); } }, handleClick: function (evt) { var target = z.event.getTarget(evt); if (z.dom.hasClass(target, "item")) { this.setCurrent(target); } } }; z.ready(function () { ToBase64.init(); });
工具链接:图片转Base64
工具效果图: