vue.js 实现图片本地预览 裁剪 压缩 上传功能


Posted in Javascript onMarch 01, 2018

以下代码涉及 Vue 2.0 及 ES6 语法。

目标

纯 javascrpit 实现,兼容ie9及以上浏览器,在本地做好文件格式、长宽、大小的检测,减少浏览器交互。

现实是残酷的,为了兼容Ie9 还是用上了 flash,第二篇来解释解释。

代码结构

<div id="wrap">
 <label>
  点我上传图片
  <input type='file' @change="change" ref="input">
 </label>
 <img :src="src" ref="img">
</div>
new Vue({
 el: '#wrap',
 data: {
  // 一张透明的图片
  src:'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 
  elInput: null
 },
 methods: {
  change(e){
   // ...
  }
 }
})

如何获取图片大小

现代浏览器中十分简单

function getSize(e){
 return e.target.files[0].size;
}

但 ie9 下暂时没有找到纯 JS 的方案。

因此,在需要判断大小时,遇到 ie9 直接绕过不去判断

如何预览本地图片

const refs = this.$refs
const elInput = refs.input
const elImg = refs.img

现代浏览器中,通过调用 FileReader 读取本地图片,将图片地址转成 Base64 格式实现预览。

function getSrc(){
 const reader = new FileReader();
 reader.onload = (e) => {
  const src = e.target.result;
  elImg.src = src;
 };
 if (elInput.files && elInput.files[0]) {
  reader.readAsDataURL(elInput.files[0]);
 }
}

但是问题又来了,ie9 并不支持 FileReader,但可以通过 ie 滤镜显示。

function getSrc(){
 elInput.select();
 elInput.blur();
 const src = document.selection.createRange().text;
 document.selection.empty();
 elImg.style.filter = `progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='${src}')`;
}

滤镜中 sizingMethod='scale' 的写法是为了图片能适应内容缩放。

由于 IE9 对安全限制有所增强,实践中会遇到以下两个问题:

如果 file 控件获得焦点,则 document.selection.createRange() 拒绝访问,因此需要在 elInput.select() 后面加一句 elInput.blur() 即可。

为了让上传按钮更美观,默认给 input[type=file] 的设置了样式 visible:hidden ,这样会导致 ie9 下报错。应该会被浏览器认为欺骗用户点击,只好曲线救国。

label{
 overflow:hidden;
}
label input[type='file']{
 position:absolute;
 top:9999px;
 left:9999px;
}

如何获取图片长宽

同理,利用 ie 滤镜和 FileReader 的方案对 ie9 和非 ie9 分别实现。

ie9 的方案

参数 src 接受的是本地图片路径

let tempEl;
const getSizeIncompatible = (src, callback) => {
 if (!tempEl) {
  tempEl = document.createElement('div');
  tempEl.style.position = 'absolute';
  tempEl.style.width = '1px';
  tempEl.style.height = '1px';
  tempEl.style.left = '-9999px';
  tempEl.style.top = '-9999px';
  tempEl.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=image)';
  document.body.insertBefore(tempEl, document.body.firstChild);
 }
 tempEl.filters.item('DXImageTransform.Microsoft.AlphaImageLoader').src = src;
 callback(tempEl.offsetWidth, tempEl.offsetHeight);
};

其中 sizingMethod='image' 是为了图片显示原始大小。

非 ie9 方案

参数 src 接受的是 base64 编码后的图片路径

const getSize = (src, callback) => {
 const image = new Image();
 image.onload = () => {
  callback(image.width, image.height);
 };
 image.src = src;
};

参考

https://elemefe.github.io/ima...

总结

以上所述是小编给大家介绍的vue.js 实现图片本地预览 裁剪 压缩 上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery ul标签下拉菜单演示代码
Dec 11 Javascript
JavaScript自定义DateDiff函数(兼容所有浏览器)
Mar 01 Javascript
jquery点击缩略图切换视频播放特效代码分享
Sep 15 Javascript
jQuery实现悬浮在右上角的网页客服效果代码
Oct 24 Javascript
JQuery移动页面开发之屏幕方向改变与滚屏的实现
Dec 03 Javascript
jQuery事件的绑定、触发、及监听方法简单说明
May 10 Javascript
利用Vue.js指令实现全选功能
Sep 08 Javascript
jQuery插件zTree实现删除树节点的方法示例
Mar 08 Javascript
vue实现选项卡及选项卡切换效果
Apr 24 Javascript
JavaScript数据结构与算法之二叉树添加/删除节点操作示例
Mar 01 Javascript
JS script脚本中async和defer区别详解
Jun 24 Javascript
vue 防止页面加载时看到花括号的解决操作
Nov 09 Javascript
vue中使用cropperjs的方法
Mar 01 #Javascript
cropper js基于vue的图片裁剪上传功能的实现代码
Mar 01 #Javascript
Vuex中mutations与actions的区别详解
Mar 01 #Javascript
vue 实现剪裁图片并上传服务器功能
Mar 01 #Javascript
解决easyui日期时间框ie的兼容的问题
Mar 01 #Javascript
详解Immutable及 React 中实践
Mar 01 #Javascript
解决VUEX兼容IE上的报错问题
Mar 01 #Javascript
You might like
浅谈php中urlencode与rawurlencode的区别
2016/09/05 PHP
php mysql操作mysql_connect连接数据库实例详解
2016/12/26 PHP
php获取数据库中数据的实现方法
2017/06/01 PHP
Laravel获取当前请求的控制器和方法以及中间件的例子
2019/10/11 PHP
Js 订制自己的AlertBox(信息提示框)
2009/01/09 Javascript
JavaScript 学习点滴记录
2009/04/24 Javascript
超酷的网页音乐播放器DewPlayer使用方法
2010/12/18 Javascript
Javascript 面向对象编程(一) 封装
2011/08/28 Javascript
浅谈JavaScript 中有关时间对象的方法
2016/08/15 Javascript
原生js实现ajax方法(超简单)
2016/09/20 Javascript
JS button按钮实现submit按钮提交效果
2016/11/01 Javascript
JavaScript cookie详解及简单实例应用
2016/12/31 Javascript
JS检索下拉列表框中被选项目的索引号(selectedIndex)
2019/12/17 Javascript
Vue触发input选取文件点击事件操作
2020/08/07 Javascript
vue中jsonp插件的使用方法示例
2020/09/10 Javascript
[37:22]DOTA2上海特级锦标赛D组资格赛#2 Liquid VS VP第一局
2016/02/28 DOTA
[48:56]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 VG vs KG
2018/03/31 DOTA
详解Django中Request对象的相关用法
2015/07/17 Python
使用pandas模块读取csv文件和excel表格,并用matplotlib画图的方法
2018/06/22 Python
Python 将Matrix、Dict保存到文件的方法
2018/10/30 Python
Python实现堡垒机模式下远程命令执行操作示例
2019/05/09 Python
PyTorch 对应点相乘、矩阵相乘实例
2019/12/27 Python
PyTorch中topk函数的用法详解
2020/01/02 Python
Python多线程操作之互斥锁、递归锁、信号量、事件实例详解
2020/03/24 Python
Lime Crime官网:美国一家主打梦幻精灵系的彩妆品牌
2019/03/22 全球购物
JDO的含义
2012/11/17 面试题
什么是serialVersionUID
2016/03/04 面试题
化工专业推荐信范文
2013/11/28 职场文书
建筑公司文秘岗位职责
2013/11/29 职场文书
学雷锋宣传标语
2014/06/25 职场文书
物流专业专科生职业生涯规划书
2014/09/14 职场文书
工人先锋号申报材料
2014/12/29 职场文书
员工家属慰问信
2015/03/24 职场文书
2016年“9.22”世界无车日活动小结
2016/04/05 职场文书
诺贝尔奖获得者名言100句:句句启人心智,值永久收藏
2019/08/09 职场文书