这篇博客已经想写很久了,由于时间问题,一直放着,没动笔。
一、我们先来讲讲上传单张图片并预览的问题。
我们先看下效果图,再来讲解。
上面的图是一张默认的头像图片和input file文本框重合的效果图。
我们来看下html代码
<img src="__STATIC__/uploads/moren/moren.jpg" style="height: 100px;width: 100px" id="headimg">
<input type="file" name="headpic" id="headpic"
onchange="uphead(this)" style="position: absolute;opacity: 0;cursor: pointer;height: 100px;width: 100px;left: 15px;top: 0px;">
这里用了一个绝对定位和透明度为0 的样式来和一个img标签的图片重合。我们可以看到在input file文本框中定义了一个onchange事件。这个onchange事件,是用来做图片回显用的。我们来看下js代码
<script>
function uphead(event) {
//获取展示图片的区域
var img = document.getElementById("headimg");
//获取文件对象
let file = event.files[0];
//获取文件阅读器
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function() {
//给img的src设置图片url
img.setAttribute("src", this.result);
}
}
</script>
FileReader
对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File
或 Blob
对象指定要读取的文件或数据。
其中File对象可以是来自用户在一个<input>
元素上选择文件后返回的FileList
对象,也可以来自拖放操作生成的 DataTransfer
对象,还可以是来自在一个HTMLCanvasElement
上执行mozGetAsFile()
方法后返回结果。
开始读取指定的Blob
中的内容。一旦完成,result
属性中将包含一个data:
URL格式的字符串以表示所读取文件的内容。
处理load
事件。该事件在读取操作完成时触发。
文件的内容。该属性仅在读取操作完成后才有效,数据的格式取决于使用哪个方法来启动读取操作。
到这里就实现了文件预览功能。如图所示
但并没上传到数据库。这里就要用formdata这个方法
var formdata = new FormData();
var file = $("input[type='file']")[0].files[0];
formdata.append("img", file);
$.ajax({
url: 'ad_addUser',
type: 'POST',
data: formdata,
cache:false,//上传文件不需要有缓存
contentType:false,//不设置内容类型
processData:false,//不处理发送的数据
success:function (data1) {
console.log(data1);
}
})
下面的代码将创建一个空的FormData对象:
var formData = new FormData(); // 当前为空
你可以使用FormData.append
来添加键/值对到表单里面;
formData.append('username', 'Chris');
到这里我们通过ajax就可以去后台PHP的控制器中的一个接口来操作上传文件了
$file = $this->request->file('img');//上传的文件名字,看formdata中append方法的命名
if ($file) {
// 进行文件上传
$info = $file->rule('md5')->move('./static/uploads/');
// 获取上传文件的目录
$saveName = $info->getsaveName();
$str = "./uploads/" . $saveName;
// strtr 字符串替换函数 -> 将路径的\\替换成
$str1 = strtr($str, '\\', '/');
return $str1;
}
到这里我们return返回就是ajax打印的data1。这个就是上传文件的路径。接着就可以用这个路径添加到数据库了。这一步就不说了,很简单。
二、多图上传,且预览的问题.这个就不详细讲了,差不多,贴上代码。需要注意的多图上传,也有删除图片的功能,这里要定义一个空数组来存放存放剩下的图片,当你点击图片的删除按钮的时候,就会把剩下的图片存到那个空数组中,用这个数组中值来上传图片
效果图
html代码。这里要加个multiple属性,这样就能多图上传了。
<div class="form-group">
<label for="file" class="col-sm-2 control-label">轮播图相册<span class="required" aria-required="true">*</span></label>
<div class="col-sm-3" id="ok">
<div class="uploadImgBtn" id="uploadImgBtn">
<input class="uploadImg" type="file" name="file" multiple id="file">
</div>
</div>
</div>
接着js
//多图上传回显
$("#uploadImgBtn").click(function(){
$("#file").on("change" , function(){
var files = this.files;
$.each(files,function(key,value){
var div = document.createElement("div");//创建节点
var img = document.createElement("img");
var a =document.createElement("a");
var png =document.createElement("img");
div.className = "pic";//定义div的类名为pic
img.className = "read";
img.id =key;
png.className ="delete";
var fr = new FileReader();
fr.onload = function(){
img.src = this.result;
a.href ="#";
// png.src ='__STATIC__/admin/images/delete.png';
png.src ='../static/admin/images/delete.png';
div.appendChild(img);
div.appendChild(a);
a.appendChild(png);
document.body.appendChild(div);
document.getElementById("ok").appendChild(div);
}
fr.readAsDataURL(value);
})
})
$("#file").removeAttr("id");
var newInput = '<input class="uploadImg test" type="file" name="file" multiple id="file">';
$(this).append($(newInput));
})
//图片删除事件
$(document).on('mouseenter', '.pic', function() {
$(this).find(".delete").show();
})
$(document).on('mouseleave', '.pic', function() {
$(this).find(".delete").hide();
})
$(document).on('click', '.delete', function() {
var id =$(this).parent().prev().attr('id');
var dd =$("input[name='file']")[0].files;
// Array.prototype.push.apply(arrfiles,dd);//性能太慢
// arrfiles.splice(id,1);
array =Object.values(dd);
array.splice(id,1);
$(this).parents('.pic').remove();
})
//多图上传信息
//循环添加到formdata中 这里要在name中定义个数组 踩坑了
var files =$("input[name='file']")[0].files;
var formdatas =new FormData();
if(array.length==0){//如果数组长度为0就是没有点击删除图片事件
// var files =$("input[name='file']")[0].files;
for (var i=0;i<files.length;i++){
formdatas.append('imgs[]',files[i])
}
}else{
for(var i=0;i<array.length;i++){
formdatas.append('imgs[]',array[i]);
}
}
//formdatas.delete('imgs[]');//切记删除文件的时候就不能delete了,因为键名一样
php
$files = $this->request->file('imgs');
if ($files) {
$str1 ='';
foreach ($files as $img) {
$info = $img->move('./static/uploads/');
$savename = $info->getSaveName();
$str = "./uploads/" . $savename;
$str1 .= strtr($str, '\\', '/');
}
return $str1;
}