文本域實現圖片拖拽上傳

  • 2019 年 12 月 17 日
  • 筆記

文件拖拽上傳

相信你看到過不少文件拖拽上傳的功能,很多論壇、社區比比皆是。所以今天就來操作一番。

Rovak/InlineAttachment 這款包就是專門實現拖拽上傳的。

安裝

將安裝包下載下來。如果你安裝了 Bower

 bower install inline-attachment

使用

先來說下 Jquery 的使用

引入相關 JS

<script src="../src/inline-attachment.js"></script>  <script src="../src/jquery.inline-attachment.js"></script>

頁面當中編寫一個文本域

<textarea name="post" rows="10"></textarea>

編寫 JavaScript 腳本

$('.post').inlineattachment({       uploadUrl: 'upload_image',  //圖片上傳處理路,       extraParams: {              '_token': 'csrf_token',       },   //laravel csrf 其他可不傳  });

接下來處理圖片上傳的功能(具體上傳的代碼可參考 demo/upload_attachment.php) 我這裡使用 Larave 來進行上傳,將其封裝了一個上傳類(具體來自 Laravel 教程 – Web 開發實戰進階 ( Laravel 5.5 )

<?php    namespace AppHandlers;    class ImageUploadHandler  {      // 只允許以下後綴名的圖片文件上傳      protected $allowed_ext = ["png", "jpg", "gif", 'jpeg'];        public function save($file, $folder, $file_prefix)      {          // 構建存儲的文件夾規則,值如:uploads/images/avatars/201709/21/          // 文件夾切割能讓查找效率更高。          $folder_name = "uploads/images/$folder/" . date("Ym/d", time());            // 文件具體存儲的物理路徑,`public_path()` 獲取的是 `public` 文件夾的物理路徑。          // 值如:/home/vagrant/Code/larabbs/public/uploads/images/avatars/201709/21/          $upload_path = public_path() . '/' . $folder_name;            // 獲取文件的後綴名,因圖片從剪貼板里黏貼時後綴名為空,所以此處確保後綴一直存在          $extension = strtolower($file->getClientOriginalExtension()) ?: 'png';            // 拼接文件名,加前綴是為了增加辨析度,前綴可以是相關數據模型的 ID          // 值如:1_1493521050_7BVc9v9ujP.png          $filename = $file_prefix . '_' . time() . '_' . str_random(10) . '.' . $extension;            // 如果上傳的不是圖片將終止操作          if ( ! in_array($extension, $this->allowed_ext)) {              return false;          }            // 將圖片移動到我們的目標存儲路徑中          $file->move($upload_path, $filename);            return [              'path' => config('app.url') . "/$folder_name/$filename"          ];      }  }

在自己的控制器中使用依賴注入的方式引入

public function uploadImage(Request $request, ImageUploadHandler $uploader)  {      // 判斷是否有上傳文件,並賦值給 $file      if ($file = $request->file('image')) {          // 保存圖片到本地          $result = $uploader->save($request->image, 'posts', Auth::id(), 1024);          // 圖片保存成功的話          if ($result) {              //$data['filename'] = $result['path'];              return [                  'filename' =>  $result['path']              ];          }          else{              return [                  'error' => 'Error while uploading file'              ];          }      }  }

這樣就實現了圖片拖拽上傳了。

如果我們的編輯器使用的是其他 Markdown 編輯器,同樣我們要實現拖拽上傳,繼續使用 jQuery 是不能滿足的。因此我們採用第二種方式。

codemirror 實現

引入相關JS

注意區別第一種方式。不要引錯,具體是 codemirror.inline-attachment.js

<script src="js/inline-attachment.js"></script>  <script src="js/codemirror.inline-attachment.js"></script>

編寫 JavaScript

inlineAttachment.editors.codemirror4.attach(simplemde.codemirror, {      uploadUrl: '/upload_image',      uploadFieldName: "image",      //urlText: "n ![file]({filename})nn",      extraParams: {          '_token': 'csrf_token',      },      onFileUploadResponse: function (xhr) {          var result = JSON.parse(xhr.responseText),              filename = result[this.settings.jsonFieldName];            if (result && filename) {              var newValue;              if (typeof this.settings.urlText === 'function') {                  newValue = this.settings.urlText.call(this, filename, result);              } else {                  newValue = this.settings.urlText.replace(this.filenameTag, filename);              }              var text = this.editor.getValue().replace(this.lastValue, newValue);              this.editor.setValue(text);              this.settings.onFileUploaded.call(this, filename);          }          return false;      }  });

至於其他和第一種沒有區別,這樣就可以實現在使用編輯器的情況下,上傳圖片了。