摘要:當(dāng)拖動(dòng)的元素或文本選擇離開(kāi)有效的放置目標(biāo)時(shí),會(huì)觸發(fā)此事件。以及對(duì)象在拖放交互期間傳輸?shù)臄?shù)據(jù)。
17-3-2更新: 謝謝@mengdu 補(bǔ)充的關(guān)于圖片預(yù)覽的另一種更簡(jiǎn)單方法 URL.createObjectURL(),具體在文章里補(bǔ)充
之前用Vue做了一個(gè)基礎(chǔ)的組件vue-img-inputer,下面就叫vii,記錄下在開(kāi)發(fā)過(guò)程中遇到的知識(shí)點(diǎn)(都算比較基礎(chǔ),具體代碼不會(huì)貼太多,都可以在項(xiàng)目倉(cāng)庫(kù)里看到)。
上傳文件很多項(xiàng)目都要用到,一些組件庫(kù)里(ele/iview...)文件上傳組件都是做成了標(biāo)配,雖然vii和uploader定位還是有些差別,但實(shí)現(xiàn)上都有幾個(gè)共同要點(diǎn):
先上demo樣子要好看點(diǎn)
圖片/文件選擇后預(yù)覽
實(shí)現(xiàn)拖拽選擇文件
圖片選擇后執(zhí)行某些動(dòng)作(譬如uploader的上傳等)
注: 下面有些地方會(huì)有些啰嗦,請(qǐng)選擇觀看
基礎(chǔ)首先我們有個(gè)文件選擇框,恩,長(zhǎng)這樣:
好丑?。。∥覀儊?lái)讓它變好看點(diǎn):
第一個(gè)方法:修改自身CSS這里有一個(gè)shadowDOM的概念,簡(jiǎn)單的來(lái)說(shuō)就是我們經(jīng)常用到的一些HTML標(biāo)準(zhǔn)組件(例如viedo,甚至滾動(dòng)條)其實(shí)是由若干個(gè)更基礎(chǔ)的DOM由瀏覽器封裝成的,使得我們調(diào)用只要一個(gè)標(biāo)簽就夠了,這類(lèi)也就是WebComponent,這里具體不展開(kāi)了。我們先來(lái)看下file-input的內(nèi)部是如何的(chrome devtool不設(shè)置是看不到的):
所以呢,這個(gè)隱藏在革命碉堡里的button就是我們直接修改file-input樣式但是卻去不掉丑按鈕的元兇??!
解決思路的:我們要么把按鈕移出視線,要么就用這個(gè)按鈕修改其樣式。
這里就修改下里面這個(gè)type=button的樣式,只提供個(gè)思路,代碼:
有沒(méi)有想到chrome修改滾動(dòng)條樣式呢?哈哈,其實(shí)是一個(gè)道理,現(xiàn)在file-input變這樣了:
好像挺簡(jiǎn)單!然而我們看到-webkit-就應(yīng)該知道兼容性了,這種方法只有safari和chrome笑笑,其他GG,所以自然不能這么干。
第二個(gè)方法:給file-input找個(gè)替身是這樣,我們可以可以把file-input整個(gè)移出視線,再找個(gè)找?guī)讉€(gè)元素,通過(guò)點(diǎn)擊這些個(gè)元素來(lái)代理原file-input的點(diǎn)擊,呼出文件選擇框呢?
自然是可以的,label標(biāo)注標(biāo)簽, 給label一個(gè)for屬性指向input的唯一id,這樣點(diǎn)擊label就相當(dāng)于點(diǎn)擊input, 所以我們可以這么寫(xiě):
.box { position: relative; } input { position: absolute; left: -9999px; } /* 使label充滿整個(gè)box*/ label { position: absolute; top: 0;left: 0;right: 0;bottom: 0; z-index: 10; /* 這個(gè)z-index之后說(shuō)到*/ }
這樣子做之后,就有一個(gè)組件的影子了,其中
因?yàn)?b>label充滿了整個(gè)box,所以點(diǎn)擊box就可以選擇文件
同時(shí)有了box,可以往里面填充任何元素,譬如一個(gè)icon
:)
好了,基礎(chǔ)基本上啰嗦完了,正式進(jìn)入vue的實(shí)現(xiàn)(Vue 2.x):
文件選擇的處理這塊講文件數(shù)據(jù)的獲取和處理:
v-model如果問(wèn)你vue里你想要組件綁定一個(gè)輸入值的最粗暴的方式是什么?v-model啊!但是這條指令其實(shí)是一個(gè)語(yǔ)法糖:
...
// 給個(gè)img來(lái)承擔(dān)預(yù)覽工作就行了 ...
當(dāng)然了,這東西的兼容性有點(diǎn)捉雞: IE10+, 移動(dòng)端可以快樂(lè)的使用。
URL.createObjectURL文檔在這,這個(gè)方法其實(shí)很直觀,唯一需要注意的是對(duì)臨時(shí)路徑的銷(xiāo)毀,來(lái)看下代碼:
... imgPreview (file) { let self = this; // 看支持不支持FileReader if (!file || !URL.createObjectURL) return; if (/^image/.test(file.type)) { // 創(chuàng)建一個(gè)reader let this.dataUrl = URL.createObjectURL(file) } }, handleFileChange (e) { // 每次重新選擇都需要進(jìn)行對(duì)上一次的銷(xiāo)毀 this.dataUrl && URL.revokeObjectURL(dataUrl) ... this.file = inputDOM.files[0]; ... // 在獲取到文件對(duì)象進(jìn)行預(yù)覽就行了! this.imgPreview(this.file); ... } ...
代碼一下子少了幾行直觀了不少哈哈哈,兼容性也是IE10+, 移動(dòng)端安卓4.0+,safari6.0+
預(yù)覽就這么完成了,下一個(gè)我們來(lái)說(shuō)拖拽!
拖拽選擇拖拽說(shuō)白了就是一個(gè)事件監(jiān)聽(tīng),drop事件,我們從頭開(kāi)始說(shuō)起
瀏覽器拖拽事件首先,放DragEVent的MDN文檔,重點(diǎn)是下面四個(gè)事件及解釋?zhuān)?/p>
dragenter
當(dāng)拖動(dòng)的元素或選擇文本輸入有效的放置目標(biāo)時(shí),會(huì)觸發(fā)此事件。dragleave
當(dāng)拖動(dòng)的元素或文本選擇離開(kāi)有效的放置目標(biāo)時(shí),會(huì)觸發(fā)此事件。dragover
當(dāng)將元素或文本選擇拖動(dòng)到有效放置目標(biāo)(每幾百毫秒)上時(shí),會(huì)觸發(fā)此事件。drop
當(dāng)在有效放置目標(biāo)上放置元素或選擇文本時(shí)觸發(fā)此事件。
以及dataTransfer對(duì)象:在拖放交互期間傳輸?shù)臄?shù)據(jù)。
獲取方法: event.dataTransfer
為什么要關(guān)注著幾個(gè)呢?因?yàn)?strong>瀏覽器是自身監(jiān)聽(tīng)這幾個(gè)拖放事件的??!譬如你把圖片或者pdf拖進(jìn)瀏覽器里。瀏覽器是會(huì)試圖打開(kāi)這個(gè)文件的,所以我們要干掉默認(rèn)行為,很簡(jiǎn)單e.preventDefault():
... methods: { preventDefaultEvent (eventName) { document.addEventListener(eventName, function (e) { e.preventDefault(); }, false) }, }, mounted () { // 阻止瀏覽器默認(rèn)的拖拽時(shí)事件,測(cè)試阻止這幾個(gè)就夠了,不放心就全阻止一遍吧 ["dragleave", "drop", "dragenter", "dragover"].forEach(e => { this.preventDefaultEvent(e); }); } ...
做完這一步,我們只需監(jiān)聽(tīng)目標(biāo)上的drop事件就行了,稍微改造下代碼:
...
其實(shí)到這里重要的點(diǎn)都講了,接下來(lái)說(shuō)些其他的
上傳uploader的話選擇完圖片在handleFileChange里直接執(zhí)行個(gè)請(qǐng)求上傳
在父組件里獲取值該怎么傳怎么傳
其他一些東西當(dāng)頁(yè)面中需要多個(gè)inputer時(shí),同一個(gè)input的id會(huì)沖突,所以不指定的情況下需要個(gè)唯一id:
...vue ...
input原本可以指定接收的文件格式,會(huì)在選擇框出來(lái)的時(shí)候默認(rèn)無(wú)法選擇非指定格式的文件
移動(dòng)端允許拍照選擇
最后
暫時(shí)就這么多了,完整的源碼在這里
有任何講的不對(duì)不好的地方請(qǐng)大力指正!
順便打下廣告,喜歡就不妨star下vue-img-inputer吧!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/81791.html
摘要:老姚淺談怎么學(xué)鑒于時(shí)不時(shí),有同學(xué)私信問(wèn)我老姚,下同怎么學(xué)前端的問(wèn)題。擼碼聽(tīng)歌,全局控制。 淺析用 js 解析 xml 的方法 由于項(xiàng)目上需要解析 xml,于是各種百度,然后自己總結(jié)了下各個(gè)主流瀏覽器解析 xml 的方法,只能是很淺顯的知道他的用法,但是還沒(méi)有深層次的研究。 裝 X - 建立自己的斗圖網(wǎng)站庫(kù) 之前加過(guò)一個(gè)斗圖群,看到很多經(jīng)典的表情,然后就收藏到了 QQ, 迫于本屌絲開(kāi)不起...
摘要:網(wǎng)址功能單圖多圖上傳圖片上傳預(yù)覽上傳進(jìn)度條分組上傳,分組查詢新建分組,刪除分組刪除圖片選擇圖片目錄結(jié)構(gòu)前端利用搭建,中引入子組件。實(shí)現(xiàn)分組的新增查詢刪除。利用模塊實(shí)現(xiàn)刪除文件功能。 公司要寫(xiě)一些為自身業(yè)務(wù)量身定制的的組件,要基于Vue,寫(xiě)完后擴(kuò)展了一下功能,選擇寫(xiě)圖片上傳是因?yàn)樽约褐耙恢睂?duì)這個(gè)功能比較迷糊,所以這次好好了解了一下。演示在網(wǎng)址打開(kāi)后的show.gif中。 使用技術(shù):Vu...
摘要:,至此咱們的微信小程序的簡(jiǎn)單使用及了解算是分享完了,畢竟個(gè)人也是道行有限,沒(méi)有鉆研太深,這些只是本人在實(shí)際項(xiàng)目開(kāi)發(fā)過(guò)程中用到和總結(jié)的經(jīng)驗(yàn),有太多不足或不對(duì)的地方,希望大家多多給予指出與改正,咱們一起來(lái)共同學(xué)習(xí)與進(jìn)步 微信小程序是一種不需要下載安裝即可使用的應(yīng)用,在國(guó)內(nèi)它在企業(yè)推廣中的受歡迎度以及就這兩年的使用及普及熱度,然而就是因?yàn)樗膫涫軞g迎度以及越來(lái)越被企業(yè)所重視,也就形成了咱們開(kāi)...
摘要:,至此咱們的微信小程序的簡(jiǎn)單使用及了解算是分享完了,畢竟個(gè)人也是道行有限,沒(méi)有鉆研太深,這些只是本人在實(shí)際項(xiàng)目開(kāi)發(fā)過(guò)程中用到和總結(jié)的經(jīng)驗(yàn),有太多不足或不對(duì)的地方,希望大家多多給予指出與改正,咱們一起來(lái)共同學(xué)習(xí)與進(jìn)步 微信小程序是一種不需要下載安裝即可使用的應(yīng)用,在國(guó)內(nèi)它在企業(yè)推廣中的受歡迎度以及就這兩年的使用及普及熱度,然而就是因?yàn)樗膫涫軞g迎度以及越來(lái)越被企業(yè)所重視,也就形成了咱們開(kāi)...
摘要:,至此咱們的微信小程序的簡(jiǎn)單使用及了解算是分享完了,畢竟個(gè)人也是道行有限,沒(méi)有鉆研太深,這些只是本人在實(shí)際項(xiàng)目開(kāi)發(fā)過(guò)程中用到和總結(jié)的經(jīng)驗(yàn),有太多不足或不對(duì)的地方,希望大家多多給予指出與改正,咱們一起來(lái)共同學(xué)習(xí)與進(jìn)步 微信小程序是一種不需要下載安裝即可使用的應(yīng)用,在國(guó)內(nèi)它在企業(yè)推廣中的受歡迎度以及就這兩年的使用及普及熱度,然而就是因?yàn)樗膫涫軞g迎度以及越來(lái)越被企業(yè)所重視,也就形成了咱們開(kāi)...
閱讀 2233·2019-08-30 15:53
閱讀 2462·2019-08-30 12:54
閱讀 1208·2019-08-29 16:09
閱讀 734·2019-08-29 12:14
閱讀 761·2019-08-26 10:33
閱讀 2485·2019-08-23 18:36
閱讀 2962·2019-08-23 18:30
閱讀 2124·2019-08-22 17:09