w3HexSchool
. javascript
有時可以看到 , 將圖片拖曳至此上傳圖片的區塊 ( ex : HackMD 的編輯區塊 ) , 這個東西是如何實現的呢 ?
Tree 查過之後 , 發現其中有 2 個重要的 Browser API 需要了解後才能製作
const reader = new FileReader(); // 建立檔案讀取器 , 將上傳的圖片資料取出
reader.onload = (e => img.src = e.target.result); // 註冊讀取完成後 , 執行的動作
reader.readAsDataURL(file); // 取出 file 中的 base64 格式 data
進入
區塊時觸發離開
區塊時觸發移動
時觸發放開
拖曳的圖片時觸發上述 Drap API 預設動作皆為
轉址到檔案位置
,
因此需要 防止預設事件preventDefault
和 終止事件傳導stopPropagation
了解 API 的基礎原理後 , 讓我們開始製作一個 圖片拖曳的預覽區塊吧 !
建立一個 upload_zone
<div id="upload_zone" class="upload_zone">
請將要上傳的圖片拖曳至此
</div>
將 upload_zone 上底色
.upload_zone {
width: 200px;
height: 200px;
margin: 20px;
padding: 10px;
cursor: pointer;
background-color: aqua;
}
建立
dragenter
.dragover
.drop
的函數 , 以防止預設事件 & 終止事件傳導 ( 避免圖片拖曳造成的轉址問題 )
function dragenter(e) {
e.stopPropagation(); //終止事件傳導
e.preventDefault(); //終止預設行為
}
function dragover(e) {
e.stopPropagation(); //終止事件傳導
e.preventDefault(); //終止預設行為
}
function drop(e) {
e.stopPropagation(); //終止事件傳導
e.preventDefault(); //終止預設行為
}
註冊
dragenter
.dragover
.drop
事件到upload_zone
const dropbox = document.getElementById("upload_zone");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
設定
dragenter
事件觸發後的樣式 A
.upload_zone_enter {
border: 10px dashed black;
background-clip: content-box;
}
dragenter
時追加樣式 A ,dragleave
時移除樣式 A 到upload_zone
const dragleave = () => dropbox.classList.remove("upload_zone_enter");
function dragenter(e) {
+ dropbox.classList.add("upload_zone_enter");
e.stopPropagation(); //終止事件傳導
e.preventDefault(); //終止預設行為
}
dropbox.addEventListener("dragleave", dragleave, false);
將 Drag 的圖片顯示到 preview 中
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
const file = files[i];
const imageType = /image.*/;
if (!file.type.match(imageType)) {
continue;
}
const img = document.createElement("img");
img.classList.add("preview_image");
img.file = file;
preview.appendChild(img); // 將圖片加到 preview 上
const reader = new FileReader();
reader.onload = (e => img.src = e.target.result);
reader.readAsDataURL(file);
}
}
function drop(e) {
e.stopPropagation();
e.preventDefault();
+ const dt = e.dataTransfer;
+ const files = dt.files; // 取得被拖曳的圖片
+ handleFiles(files);
+ dropbox.classList.remove("upload_zone_enter");
}
設定 preview 中的圖片樣式
.preview_image {
width: 200px;
height: 200px;
}
完成上方設定後 , 將會得到下方圖片之效果
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing