移动端HTML5 文件预览及上传
2018-02-07 17:04
211 查看
本文主要介绍使用HTML5 图片上传及上传前的预览。本人是做PHP后端的,由于前端有时也需要自己写,有空就研究了下图片上传预览,写的都是原生代码,废话不多说,直接上代码。
前端代码
看效果:
在google chrome 浏览器打开效果
手机uc浏览器打开
在手机浏览器打开会调用手机摄像头进行拍摄。
抛开美观不说,暂且讨论下兼容性,除了苹果safari没测试外,在现在主流浏览器上(ie8以上级别),展示效果差不多。
下面开始讲解代码(关键部分代码)
文件预览主要是用到了这个webApi :FileReader
首先是新建了一个FileReader 对象,然后是readAsDataURL(file),该方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成(DONE),并触发 loadend 事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。 在读取操作完成时触发reader.onload事件,在该事件出来处理中,将读取的图片内容赋值给生成的img dom的src 属性。然后初始化预览图片高度(inintHW()),将base64编码内容push 到数组中。
上面注释掉的代码跟没注释的代码功能是一样的,只不过该api 有兼容性问题,我看到也有网友使用该api实现了图片预览功能,但我个人看法跟官方给的提示一样,暂时不建议使用!!!
至于FileReader 这个web api 的使用说明,详情请移步:https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
URL.createObjectURL() 用法:https://developer.mozilla.org/zh-CN/docs/Web/API/URL/createObjectURL
再看一下视频预览:
视频预览是跟图片预览原理是一样的。
不过在移动端即便这样子写
下面来看上传功能代码(只讨论图片上传):
关键代码
这里使用了ajax 和 formData ,如果不熟悉这两个知识点,请移步
ajax: https://developer.mozilla.org/zh-CN/docs/Web/Guide/AJAX
formData:https://developer.mozilla.org/zh-CN/docs/Web/API/FormData
file_preview.php 代码
讲解:首先判断上传的文件的数量,
为什么要将base64编码:data:image/png;base64 给处理掉呢?因为如果直接放到php里用base64_decode函数解码会导致最终保存的图片文件格式损坏,而解决方法就是先去掉这一base64识别部分。
整体效果图:
前端代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <title>Document</title> <style> *{ margin:0; padding:0; } ul,ol{ list-style-type:none; } .clearfix:after,.clearfix:before{ display:table; content:' '; } .clearfix:after{ clear:both } .tc{ text-align:center; } .select,.select_video{ height:2rem; line-height:2rem; background:#fff; border:1px solid #4285F4; margin:0.5rem 1rem; position:relative; } .select label,.select_video label{ width:100%; position:absolute; top:0; left:0; font-size:14px; color:#333; } #upload,#upload_video{ display:none; } .preview,.video_preview{ margin:0.5rem 1rem; border:1px solid #bbb; padding:4px; display:none; } .preview_img_list li{ float:left; width:25%; padding:2px 0; } .preview_img_list li img{ vertical-align:top; max-width:98%; } .btn{ background: #4285F4; color:#fff; height:2.5rem; line-height:2.5rem; margin:2rem 1rem; border-radius:0.5rem; } </style> <script> window.onload = function(){ var uploadBtn = document.querySelector('#upload'); var previewImgList = document.querySelector('.preview_img_list'); var uploadVideo = document.querySelector('#upload_video'); var submitBtn = document.querySelector('.submit'); imgArr = new Array(); uploadBtn.addEventListener('change',function(){ var imgLen = this.files.length; var liLen = previewImgList.getElementsByTagName('li').length; var ImgLen = imgLen + liLen ; if(ImgLen > 9){ alert("上传最大数量不能大于9"); return false; } document.querySelector(".preview").style.display = 'block'; for(var i = 0; i < imgLen;i++){ var file = this.files[i]; var imgType = /^image\//; if(!imgType.test(file.type)){ continue; } var li = document.createElement('li'); var img = document.createElement("img"); li.appendChild(img); previewImgList.appendChild(li); var reader = new FileReader(); reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; initHW(); imgArr.push(e.target.result);}; })(img); reader.readAsDataURL(file); // var objectUrl = window.URL.createObjectURL(file); // img.src = objectUrl; } },false); uploadVideo.addEventListener('change',function(){ var file = this.files[0]; var videoType = /^video\//; if(!videoType.test(file.type)){ alert("所选文件不是合法的视频文件"); return false; } var pv = document.querySelector('.video_preview'); var video = document.createElement('video'); video.setAttribute('controls','controls'); video.style.width = "100%"; pv.appendChild(video); pv.style.display = "block"; // var objectUrl = window.URL.createObjectURL(file); // video.src = objectUrl; // var reader = new FileReader(); reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(video); reader.readAsDataURL(file); video.play(); },false); submitBtn.addEventListener('click',function(){ if(!imgArr.length){ alert('请选择要上传的图片'); return false; } var form = document.querySelector('form'); var fd = new FormData(form); for(var i = 0;i < imgArr.length;i++){ fd.append('file[]',imgArr[i]); } var request = new XMLHttpRequest(); var url = "./file_preview.php"; request.open('post',url); request.send(fd); },false); } // 初始化图片宽度 // 使得图片高度一致 function initHW(){ var previewImgList = document.querySelector('.preview_img_list'); var Lis = previewImgList.getElementsByTagName('li'); var LisLen = Lis.length; if(LisLen > 1){ var img = Lis[0].getElementsByTagName('img')[0]; var imgW = img.width; var imgH = img.height; for(var i = 1; i < LisLen; i++){ var img = Lis[i].getElementsByTagName('img')[0]; img.style.width = imgW + 'px'; img.style.height = imgH + 'px'; } } } </script> </head> <body> <h2 class = "tc">图片上传及预览</h2> <form action="" > <div class="select tc" > <label for="upload">图片上传及预览</label> <input type="file" id = "upload" multiple="multiple" accpet = "image/*" capture = "camera" > </div> <div class="preview"> <ul class = "preview_img_list clearfix"> </ul> </div> <div class="select_video tc"> <label for="upload_video">视频上传及预览</label> <input type="file" id = "upload_video" accpet = "video/*" capture = "camcorder"> </div> <div class="video_preview"> </div> <div class="submit btn tc">上传</div> </form> </body> </html>
看效果:
在google chrome 浏览器打开效果
手机uc浏览器打开
在手机浏览器打开会调用手机摄像头进行拍摄。
抛开美观不说,暂且讨论下兼容性,除了苹果safari没测试外,在现在主流浏览器上(ie8以上级别),展示效果差不多。
下面开始讲解代码(关键部分代码)
文件预览主要是用到了这个webApi :FileReader
var reader = new FileReader(); reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; initHW(); imgArr.push(e.target.result);}; })(img); reader.readAsDataURL(file); // var objectUrl = window.URL.createObjectURL(file); // img.src = objectUrl; // imgArr.push(e.target.result); }
首先是新建了一个FileReader 对象,然后是readAsDataURL(file),该方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成(DONE),并触发 loadend 事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。 在读取操作完成时触发reader.onload事件,在该事件出来处理中,将读取的图片内容赋值给生成的img dom的src 属性。然后初始化预览图片高度(inintHW()),将base64编码内容push 到数组中。
上面注释掉的代码跟没注释的代码功能是一样的,只不过该api 有兼容性问题,我看到也有网友使用该api实现了图片预览功能,但我个人看法跟官方给的提示一样,暂时不建议使用!!!
至于FileReader 这个web api 的使用说明,详情请移步:https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
URL.createObjectURL() 用法:https://developer.mozilla.org/zh-CN/docs/Web/API/URL/createObjectURL
再看一下视频预览:
视频预览是跟图片预览原理是一样的。
不过在移动端即便这样子写
<input type="file" id = "upload_video" accpet = "video/*" capture = "camcorder">也不会调起手机摄像,至于为什么要这样子写,我也不是很懂,在网上查资料,看到有人这样子做,就尝试了下,果然不行,不过读取文件预览是没问题的,这里暂不考虑这个问题。
下面来看上传功能代码(只讨论图片上传):
submitBtn.addEventListener('click',function(){ if(!imgArr.length){ alert('请选择要上传的图片'); return false; } var form = document.querySelector('form'); var fd = new FormData(form); for(var i = 0;i < imgArr.length;i++){ fd.append('file[]',imgArr[i]); } var request = new XMLHttpRequest(); var url = "./file_preview.php"; request.open('post',url); request.send(fd); },false);
关键代码
fd.append('file[]',imgArr[i]);在for循环中,写成file[]是为了后台PHP 处理方便,写成这个样子,PHP后台可以把它当做数组来处理。
这里使用了ajax 和 formData ,如果不熟悉这两个知识点,请移步
ajax: https://developer.mozilla.org/zh-CN/docs/Web/Guide/AJAX
formData:https://developer.mozilla.org/zh-CN/docs/Web/API/FormData
file_preview.php 代码
<?php $imgCount = count($_POST['file']); for($i = 0;$i < $imgCount;$i++){ if(preg_match('/^(data:\s*image\/(\w+);base64,)/',$_POST['file'][$i],$result)){ $ImageType = $result[2]; $res = str_replace($result[0],'',$_POST['file'][$i]); $filePath = './'; $fileName = mt_rand().'.'.$ImageType; file_put_contents($filePath.$fileName,base64_decode($res)); }else{ return false; } }
讲解:首先判断上传的文件的数量,
$imgCount = count($_POST['file']);然后循环处理,正则匹配文件名后缀,
preg_match('/^(data:\s*image\/(\w+);base64,)/',$_POST['file'][$i],$result),获取文件名后缀:
$ImageType = $result[2];,然后将类似data:image/png;base64,头给处理掉:
$res = str_replace($result[0],'',$_POST['file'][$i]);,然后保存图片到服务器:
file_put_contents($filePath.$fileName,base64_decode($res));
为什么要将base64编码:data:image/png;base64 给处理掉呢?因为如果直接放到php里用base64_decode函数解码会导致最终保存的图片文件格式损坏,而解决方法就是先去掉这一base64识别部分。
整体效果图:
相关文章推荐
- 用html5文件api实现移动端图片上传&预览效果
- 移动端HTML5实现文件上传
- javascript html5移动端轻松实现文件上传
- 利用html5的FileReader对象实现图片预览,利用FormData对象结合struts2实现无刷新文件上传(多参数)
- Ext4+Servlet+HTML5实现实时获取文件上传进度、本地预览、文件拖拽上传的相册实例
- Ext4+Servlet+HTML5实现实时获取文件上传进度、本地预览、文件拖拽上传的相册实例
- html5文件上传预览
- C# 结合html5 批量上传文件和图片预览
- 基于Bootstrap 3可预览的HTML5文件上传插件
- html5-文件:FileReader实现上传前预览
- 移动端HTML5实现文件上传
- HTML5文件上传前本地预览
- jQuery+HTML5实现上传文件预览
- 基于ajax的Html5文件上传插件,带进度并支持图片预览
- C# 结合html5 批量上传文件和图片预览
- html5 文件上传与图片预览
- ajax:html5上传文件,上传之前可以实现本地预览
- [javascript]——移动端 HTML5 图片上传预览和压缩
- 移动端HTML5实现打电话,发短信,发邮件,文件上传
- 多图片上传预览实现以及移动端web多文件上传