紹
DropzoneJS是一個(gè)提供文件拖拽上傳并且提供圖片預(yù)覽的開源類庫, 零依賴且高度可定制
官網(wǎng)和Github
官方文檔:https://www.dropzonejs.com/
中文版本:http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/#installation
Github: https://github.com/enyo/dropzone/
下載和安裝
https://raw.githubusercontent.com/enyo/dropzone/master/dist/dropzone.js
引入到我們的頁面
<script src="./path/to/dropzone.js"></script>
這是官網(wǎng)Demo的效果, 如果你也想用到這樣的效果, 可以直接到源碼包的dist文件夾下樣式拷貝過來。
Dropzone 不會(huì)處理你上傳到服務(wù)器上面的文件. 你必須自己編寫代碼實(shí)現(xiàn)接收和保存上傳的文件。
如何使用?
我們只需要?jiǎng)?chuàng)建一個(gè)class類名是dropzone的form表單元素:
<form action="/file-upload" class="dropzone" id="my-awesome-dropzone"></form>
Dropzone將查找所有的 class 屬性中包含 dropzone 的表單元素, 就是這么簡(jiǎn)單, 這些上傳文件將被正常處理就像這里是一段像下面這樣的HTML代碼:
<input type="file" name="file" />
程序化方式創(chuàng)建 dropzones
不是必須在form上, 你也可以通過js代碼初始化一個(gè)dropzone實(shí)例
// Dropzone class:
var myDropzone=new Dropzone("div#myId", { url: "/file/post"});
或者假如你用到了jquery也可以這樣寫
// jQuery
$("div#myId").dropzone({ url: "/file/post" });
配置
有兩種方式配置 dropzones.
一種就是和之前創(chuàng)建表單一樣
另一種是通過js代碼實(shí)現(xiàn), 如下
lt;!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>H5混合開發(fā)(runoob.com)</title>
<style type="text/css">
#div1{width:350px;height:70px;padding:10px;border:1pxsolid#aaaaaa;}
</style>
<script>
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<p>拖動(dòng) RUNOOB.COM 圖片到矩形框中:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="img/logo.jpg" draggable="true" ondragstart="drag(event)" width="336" height="69">
</body>
</html>
它看上去也許有些復(fù)雜,不過我們可以分別研究拖放事件的不同部分。
設(shè)置元素為可拖放
首先,為了使元素可拖動(dòng),把 draggable 屬性設(shè)置為 true :
<img draggable="true">
拖動(dòng)什么 - ondragstart 和 setData()
然后,規(guī)定當(dāng)元素被拖動(dòng)時(shí),會(huì)發(fā)生什么。
在上面的例子中,ondragstart 屬性調(diào)用了一個(gè)函數(shù),drag(event),它規(guī)定了被拖動(dòng)的數(shù)據(jù)。
dataTransfer.setData() 方法設(shè)置被拖數(shù)據(jù)的數(shù)據(jù)類型和值:
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
在這個(gè)例子中,數(shù)據(jù)類型是 "Text",值是可拖動(dòng)元素的 id ("drag1")。
放到何處 - ondragover
ondragover 事件規(guī)定在何處放置被拖動(dòng)的數(shù)據(jù)。
默認(rèn)地,無法將數(shù)據(jù)/元素放置到其他元素中。如果需要設(shè)置允許放置,我們必須阻止對(duì)元素的默認(rèn)處理方式。
這要通過調(diào)用 ondragover 事件的 event.preventDefault() 方法:
event.preventDefault()
進(jìn)行放置 - ondrop
當(dāng)放置被拖數(shù)據(jù)時(shí),會(huì)發(fā)生 drop 事件。
在上面的例子中,ondrop 屬性調(diào)用了一個(gè)函數(shù),drop(event):
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
代碼解釋:
調(diào)用 preventDefault() 來避免瀏覽器對(duì)數(shù)據(jù)的默認(rèn)處理(drop 事件的默認(rèn)行為是以鏈接形式打開)
通過 dataTransfer.getData("Text") 方法獲得被拖的數(shù)據(jù)。該方法將返回在 setData() 方法中設(shè)置為相同類型的任何數(shù)據(jù)。
被拖數(shù)據(jù)是被拖元素的 id ("drag1")
把被拖元素追加到放置元素(目標(biāo)元素)中
現(xiàn)目標(biāo):
圖1 多圖上傳效果
1、html代碼
<tr class=''>
<td width="90" align="right">相關(guān)多圖</td>
<td >
<div class='yllist yllist_x_duotu'>
<dl>
<!--存放上傳的圖片-->
<transition-group name="list">
<dd v-for="(item,index) in listData " draggable="true" :key="item"
@click="del(index)"
@mouseover="showzz(1,index)"
@mouseleave="showzz(0,index)"
@dragstart="drag($event,index)"
@drop="drop($event,index)"
@dragover='allowDrop($event)'
>
<img :src="item.picpath">
<div class='zzz none' :class="{'nonone':item.shs==1}">
<div class='zzimg '><i class="fa fa-trash-o" aria-hidden="true"></i></div>
</div>
</dd>
<!--結(jié)束-->
</transition-group>
<dd @click="upbtn" class='btnclass'><i class="fa fa-camera-retro" aria-hidden="true"></i>
<input type='file' id='multiple' accept="image/*" multiple="multiple" style='display:none' @change="autoup" name="ss">
</dd>
</dl>
<div class='clear'></div>
<div>
<span class='itemms'>說明:可以拖動(dòng)改變順序</span>
</div>
</div>
</td>
</tr>
說明:
@click="del(index)" 點(diǎn)擊刪除圖片 index為數(shù)組的索引 點(diǎn)擊的是第幾個(gè)圖片
@mouseover="showzz(1,index)" 鼠標(biāo)放到上邊 出現(xiàn)遮罩層 垃圾桶
@mouseleave="showzz(0,index)" 鼠標(biāo)離開 遮罩層消失
@dragstart="drag($event,index)" 以下三個(gè) 用于拖拽排序
@drop="drop($event,index)"
@dragover='allowDrop($event)'
draggable="true" 設(shè)置為true 可以拖動(dòng)
:key="item" 這里的key 要注意不能等于 index,要不然沒有動(dòng)畫效果
img src的屬性 是 :src="item.picpath" 不能是src={{item.picpath}}
<div class='zzz none' :class="{'nonone':item.shs==1}"> 設(shè)置遮罩層 shs=1的時(shí)候顯示
上傳的選擇框設(shè)置為display:none隱藏
transition-group用法:
<transition-group name="list"> 實(shí)現(xiàn)拖拽的動(dòng)畫效果 后邊的name可以隨意寫 ,但是要和css的.list-move {transition: transform 0.3s;} 【上邊自定義的name,我這里是list】-move 設(shè)置該css 動(dòng)畫的時(shí)間
2、js代碼
new Vue({
el: '#app',
data(){
tagslist:[
'網(wǎng)站開發(fā)',//存放的標(biāo)簽
'網(wǎng)站建設(shè)'
],
tagsdt:"", //綁定的標(biāo)簽文本框
tagindex:"",//刪除標(biāo)簽的序號(hào)(索引)
listData: [
/*
{'picpath':'/public/upload/image/20211107/1.jpg',shs:0}
shs 顯示遮罩層 ,垃圾桶刪除標(biāo)志,0 不顯示 1顯示
*/
],
file:"file", //用于切換 file text 實(shí)現(xiàn)同一個(gè)圖片可以連續(xù)上傳
tis:'', //提示內(nèi)容
showzzc:0, //彈出框的顯示,隱藏 。0 隱藏 1顯示
showts:0, //1 彈出提示操作框 2 彈出提示確認(rèn)框
lisindex:"", //記錄圖片的索引
datameth:"" //根據(jù)這里的參數(shù)操作不同的方法
}
},
methods:{
tags:function(){
if(this.tagsdt){
this.tagslist.push(this.tagsdt);
}
this.tagsdt="";
},
deltag:function(f){
this.showzzc=1;
this.showts=1;
this.tagindex=f;
this.datameth='tag';
},
hidetc:function(){
this.showzzc=0;
},
del:function(key){
this.showzzc=1;
this.showts=1;
this.lisindex=key;
this.datameth="delpic";
//this.listData.splice(key, 1);
},
isdelc:function(){
if(this.datameth=="delpic"){
this.listData.splice(this.lisindex, 1);
}
if(this.datameth=="tag"){
this.tagslist.splice(this.tagindex, 1);
}
this.showzzc=0;
},
showzz:function(meth,key){
//console.log(this.listData[key].shs);
if(!this.listData[key].shs){
this.$set(this.listData[key],'shs',0);
}
this.listData[key].shs=meth;
},
upbtn:function(){
document.getElementById("multiple").click();
},
autoup:function(){
let that=this;
that.file="text"; //切換text file
let ups=document.getElementById( "multiple");
let formdata=new FormData();
if(ups.files[0]){
if(ups.files.length>4){
this.showzzc=1;
this.showts=2;
this.tis="一次最多可以選擇4張圖片上傳!";
that.file="file";
return false;
}
for(m=0;m<=ups.files.length-1;m++){
formdata.append("file", ups.files[m]);
axios.post("/api/uppic", formdata)
.then(function (response) {
if(response.data.error=='0000'){
that.listData.push(response.data.pic);
that.file="file";//重新切換為file
//console.log(JSON.stringify(that.listData));
}else{
that.showzzc=1;
that.showts=2;
that.tis=response.data.msg;
that.file="file";
return false;
}
})
.catch(function (error) {
console.log(error);
});
}
console.log(ups.outerHTML);
}
}
})
注意:上傳圖片以后一定要that.file="file",切換回file,不然會(huì)出現(xiàn)只能上傳一次,下次選擇當(dāng)前圖片不能上傳的情況。
上邊的上傳是選取多個(gè)然后for循環(huán)逐個(gè)上傳的,也可以file使用數(shù)組file[]批量提交,如下:
for(m=0;m<=ups.files.length-1;m++){
formdata.append("file[]", ups.files[m]);
}
axios.post("/api/uppic", formdata)
但是這樣做的話,后臺(tái)使用
foreach($_FILES as $k=>$v){
}
得到的$v['name']就是數(shù)組,需要我們?cè)俅蝔or循環(huán),得到單個(gè)的圖片信息,返回以后的信息因?yàn)槭菙?shù)組,push只能一次追加一個(gè),就只能再次循環(huán),感覺很麻煩還不如開始就循環(huán),一個(gè)一個(gè)的上傳。
3、信息標(biāo)簽html
<tr class=''>
<td width="90" align="right">信息標(biāo)簽</td>
<td>
<div class="layui-input-inline tagslist" >
<span class='tagspan' v-for="(tag,key) in tagslist" :key="key" @click="deltag(key)">{{tag}}</span>
</div>
<input type="text" class='inpMain' id='tags' style='width:150px;' @blur="tags" v-model="tagsdt" /> <span class='itemms'>點(diǎn)擊標(biāo)簽可以刪除</span>
<span class='itemms'></span>
</td>
</tr>
輸入文本框綁定tagsdt,當(dāng)我們鼠標(biāo)離開該文本框的時(shí)候,通過blur使用tags方法讀取綁定的tagsdt,可以獲得輸入的內(nèi)容,這里需要判斷是否為空,如果不為空再push進(jìn)數(shù)組:this.tagslist.push(this.tagsdt);
4、php后端代碼
foreach($_FILES as $k=>$v){
$v['name'],$v['size'],$v['tem_name']
就是圖片的基本信息,使用move_uploaded_file移動(dòng)到指定文件夾
$imags['picpath']=$path;
$imags['shs']=0;
}
exit(json_encode(array('error'=>'0000','pic'=>$imags),JSON_UNESCAPED_UNICODE));
move_uploaded_file用法:
當(dāng)前文件:$v["tmp_name"],
目標(biāo)文件:ROOT_PATH.$images_dir.$newname
move_uploaded_file($v["tmp_name"], ROOT_PATH.$images_dir.$newname);
再次強(qiáng)調(diào)上傳圖片,要驗(yàn)證圖片的安全性,防止圖片木馬!
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。