白話 圖片上傳

當然這一切的一切肯定是基于IE8不支持的新特性,哈哈哈

難嗎

回答是肯定的,難! 任何不舍得花時間去研究去思考的事情都比較難,難在自己身上。
插件都是人寫出來的,那么為什么自己不可以成為那一類人,而總是去爭當用輪子的人。

起因

跟大部分人一樣,剛開始涉獵特定語言方面的技能,總是需要用別人的輪子推車。用JavaScript的話來說,那就是 各種插件各種庫。我也一樣,從一年初入前端,到現(xiàn)在也有一年多點時間了。面對各種開發(fā)需求,在個人能力范圍沒達到要求的時候也是需要去各大網(wǎng)站查找對應的功能插件。從一開始就有著一顆心,什么都系都想通過原生JS去實現(xiàn),想要掌握這門語言的特性。但是在公司生產(chǎn)過程中,我發(fā)現(xiàn)能力的不足與特殊功能開發(fā)效率的底下是我這個初級開發(fā)者無法跨過的,得用插件、庫。
而現(xiàn)在,在一定的能力支撐與一點時間的犧牲,我發(fā)現(xiàn)我更樂于去做替代插件、庫的工作;同樣帶來的好處就是,有任何問題我知道為什么會出現(xiàn),怎么修復以及怎么避免。就如同樂觀心態(tài)(給錢讓你coding)一樣,各種好處給你,不要白不要。

開始

xxx:嘰里呱啦說了一大堆,跟標題有關系嗎,Show me the code



me: 那啥,咱不是白話的嘛,code可能就放關鍵代碼怎么樣。。

流程

  • 首先的要一個 input[type=file](如果要在移動端使用 還需要加上camera 屬性,多選 multiple)
  • 處理代理點擊 (file的樣式太丑還不能改,1,代理點擊 2,在file上面浮一層 元素 pointer-event:none)
  • 監(jiān)聽file的 change 事件(*注意點A)
  • 處理文件,返回內(nèi)容
    (附加:拖拽上傳)
代理點擊

在低版本的IE下,瀏覽器處于安全原則,必須需要用戶點擊file才能觸發(fā)文件選擇。所以才有了pointer-event:none這一種解決方案。當然如果是支持高版本的瀏覽器,這些都不用care,代理觸發(fā)、點擊失效想怎么來就怎么來

監(jiān)聽

file再被觸發(fā)點擊之后,會彈出文件框(本地相冊)提供用戶選擇,當用戶選擇之后觸發(fā)了 file 的 change 事件,這個時候就可以拿到用戶所選擇的內(nèi)容了,與一般 <input> this.value不同,file 獲取 文件內(nèi)容是 通過 this.files,而這個 files 跟 arguments,NodeList 一樣,是個類數(shù)組。每個file文件能都訪問到的屬性有:


這樣 我們可以通過 file[accept] 與 File.type 進行雙重驗證,以及大小驗證等
** 注意 ** 如果上傳連續(xù)選擇同一個文件,那么將不觸發(fā)change事件,對啊,兩次都一樣,怎么能叫change,所以沒有將上傳信息返回開發(fā)者操作時,需要將file置空。然而在這個時候,IE高版本就跑出來給你找問題了,你從有數(shù)據(jù)到空數(shù)據(jù),那是不是也是change啊,它就給你觸發(fā)一次change事件,這個時候就需要在change事件中,判斷this.files.length了。

處理文件

在監(jiān)聽到change事件,拿到files之后,就可以開始對files進行各種驗證與操作了,驗證就不仔細說了,只是需要注意的一點是,驗證不通過,給出提示,結束函數(shù)時,記得置空file,不然再選擇同樣的文件,不會觸發(fā)。
處于安全性的考慮,this.files是不能夠被修改的,也就是說你不能直接的操作它,只能通過Array將他內(nèi)部的file復制到一個數(shù)組中進行操作,并作為結果返回給開發(fā)者。

       //生成本地預覽
      window.URL.createObjectURL(file);

而開發(fā)者拿到通過驗證的files之后,可以通過 new FormData() 進行數(shù)據(jù)上傳,一般來說都是通過ajax

      var form_data = new FormData();
      form_data.append(追加key,追加value);
      returnFiles.forEach( item => {
          form_data.append(上傳key,item)
    })

  而通過 ajax上傳文件 需要注意一點是 ,是要 禁止處理發(fā)送的數(shù)據(jù),與設置Content-Type請求頭,讓他們自適應去

關于拖拽上傳

那就更簡單了~ 哈? 更簡單???

步驟
  • 禁止瀏覽器默認行為,就是拖拽文件后自動打開改文件,防止用戶沒有拖拽到目標區(qū),結果頁面跳轉了
  • 監(jiān)聽制動拖拽容器的 drop 行為
  • 通過監(jiān)聽drop 拿到 e.dataTransfer.files 這就是跟file 一模一樣的 格式了。當然后你可能需要兼容一下 e 在不同瀏覽器的差異了
  • 跟file 一樣 處理文件 沒了。。。
    //脫離   dragleave
    document.addEventListener('dragleave',function(e){ 
          e.preventDefault();
           //或則
          window.event.returnValue = false; 
          return false;
    })
    // 拖放后   drop
    // 拖進    dragenter
   // 拖來拖去  dragover
  // 這四個都要禁止

  拖拽受體.addEventListener('drop',function(e){
         var _files = e.originalEvent.dataTransfer.files;
  })

結束語

這樣,你不就知道是怎么實現(xiàn)得了嘛,插件? 為何我不試試?

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容