昨天做了圖片上傳功能
但個人覺得,還是要能拖曳到編輯器中,直接上傳最方便。
我們的 SimpleMDE 的編輯區塊在這邊 class 名稱 CodeMirror-scroll
拖曳
和 釋放
事件所以我們要抓到這個區塊,加上監聽事件進行監聽
要監聽 拖曳
和 釋放
兩類動作
拖曳
有好幾個事件
但是將圖片拖曳到瀏覽器上,預設是打開圖片來瀏覽圖片
所以在監聽事件中要用 event.preventDefault()
阻止這個預設動作
這邊做 dragover
跟 drop
兩個事件的監聽,dragover
是拖曳到區塊上方,drop
是釋放圖片
如果想要 CSS 特效有圖片進入進出的效果,可以加 css 與監聽其他事件如 dragenter
或 dragleave
let items = document.getElementsByClassName('CodeMirror-scroll');
let dropArea = items[0];
dropArea.addEventListener('dragover', (event) => {
event.preventDefault();
});
dropArea.addEventListener('drop', (event) => {
event.preventDefault();
});
接下來在 drop
事件中增加上傳檔案的動作,我們可以在 event.dataTransfer.files
抓到使用者抓的複數檔案
再交由 Upload 方法處理,並檢查 file 的 type 是否是圖片格式,是的話再集中在 formData 再上傳
dropArea.addEventListener('drop', (event) => {
event.preventDefault();
const files = event.dataTransfer.files;
upladFiles(files);
});
function upladFiles(files) {
const formData = new FormData();
for (const file of files) {
if(file.type.startsWith('image')){
formData.append('image', file);
}
}
fetch('/Admin/UploadImages', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => { console.log(data); })
.catch(error => { console.error(error); });
}
後端我調整了一下,另外開了一支 API 使支援多檔案上傳
[HttpPost]
public async Task<IActionResult> UploadImages(IFormFile[] images)
{
var list = new List<string>();
foreach (var image in images)
{
var path = await UploadAsync(image);
list.Add(path);
}
return Json(list);
}
private async Task<string> UploadAsync(IFormFile image)
{
if (image == null || image.Length == 0)
{
return string.Empty;
}
var imagePath = Path.Combine(_webHostEnvironment.WebRootPath, "image");
if (!Directory.Exists(imagePath))
{
Directory.CreateDirectory(imagePath);
}
var extenrsion = Path.GetExtension(image.FileName);
var fileName = $"{Guid.NewGuid()}{extenrsion}";
using (var stream = System.IO.File.Create($"{imagePath}/{fileName}"))
{
await image.CopyToAsync(stream);
}
var webPath = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}/image/{fileName}";
return webPath;
}
取得資料後,需把連結插入編輯器中
以下幾行程式可以幫我們插入文字到編輯器裡
var pos = simplemde.codemirror.getCursor();
simplemde.codemirror.setSelection(pos, pos);
simplemde.codemirror.replaceSelection("[dannyliu](https://dannyliu.me)");
我們改造後變成如下,即大功告成
function insertImages(data){
data.forEach(item=>{insertImage(item);});
}
function insertImage(data) {
var pos = simplemde.codemirror.getCursor();
simplemde.codemirror.setSelection(pos, pos);
simplemde.codemirror.replaceSelection(`![dannyliu](${data})`);
}
詳細程式碼可以到 GitHub 看