在H5技術發展如火如荼的今天,前端再也不是頁面和切圖仔的代名詞,而今的前端早已不再是寫寫頁面擼擼簡單交互了,而今的前端相比十年前已經發生了翻天覆地的變化,像近幾年出現的,vuejs,react等等前端框架已被廣泛應用于各類在線協作平臺、中,以node為技術棧的各類平臺已經廣泛被很多大公司推出,前端已經變天了。
如果你也想更好的學習,不妨入手一本紅寶書
在之前對于圖片上傳最原始的做法就是通過在form表單中放置type為file的input標簽,然后由用戶選擇后提交上傳,但是頁面在提交的時候會刷新,這種用戶體驗非常不友好,后來出現了,借助xhr我們可以在不刷新頁面的情況下直接上傳圖片js上傳圖片到項目服務器上,用戶體驗有了較大的提升,但是還想再z做進一步優化js上傳圖片到項目服務器上,接著出現了和,我們發現可以通過借助和實現從電腦的資源管理器直接拖拽圖片到網頁上傳,具體過程是從電腦拖拽圖片到網頁,js在drop的事件中取到當前事件對象的進而得到文件對象,然后實例化對象,借助xhr異步上傳圖片,這無疑是一個錦上添花的功能,至此,對于上傳的用戶體驗已經達到了一定的高度,那么我們是不是就不能再進一步,玩點更高逼格的東西,讓用戶體驗再上一個臺階呢?
對于用慣了word、excel等桌面端軟件的用戶來說,簡單的復制粘貼就能將需要的圖片插入到需要的位置無疑是最方便的,那么我們是不是也可以在瀏覽器端實現這個功能呢?
要實現該功能,我們就需要先從剪切板中獲取到圖片,還好瀏覽器為我們提供了相關支持,代碼如下:
document.addEventListener('paste', function(event) {
const items = event.clipboardData ? event.clipboardData.items : [];
let file = null;
if (items && items.length) {
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf('image') !== -1) {
file = items[i].getAsFile();
break;
}
}
}
});
需要注意的是,不要用數組的find方法去查找圖片對象,因為items是一個偽數組,并沒有find方法。
在以上代碼中,我們全局監聽對象上的paste事件,當粘貼事件觸發時遍歷剪切版對象()中的所有items,找到類型為圖片的item并調用方法得到文件對象,拿到file 對象后我們有兩種選擇:
1、通過得到文件對象的字符串,代碼如下:
const reader = new FileReader();
reader.onload = function(e){
// 通過e.target.result取到base64然后上傳
// 作為src設到image標簽上進行預覽
}
reader.readAsDataURL(file); //此處的file為上面得到的文件對象
在得到了圖片的字符串后我們可以將其傳遞給后端,后端接受數據并存儲,如果我們需要在上傳前或者上傳過程中預覽圖片,可以直接將上面得到的數據作為src傳遞給image標簽然后預覽。
2、通過將文件對象轉換為文件流數據,代碼如下:
const formData = new FormData();
formData.append('file', file);
相比字符串的龐大,文件流上傳會是一個更優的選擇,所以這里選用來上傳文件,代碼如下:
const xhr = new XMLHttpRequest();
xhr.onload = function () {
try {
// 取得響應消息
const result = JSON.parse(this.responseText);
} catch(err) {
console.log(err)
}
};
xhr.open('POST', './upload_file.php', true);
xhr.send(formData);
當然上述代碼只是傳遞了圖片文件對象,如果除了文件外還需要傳遞其他自定義內容比如文件名,時間之類的,只需要通過對象的方法添加其他字段即可。
對于后端文件保存的實現方式多種多樣,不同人有不同的選擇,不管用node、php還是java只要用的順手都是可以的,這里簡單介紹一下php的實現,代碼如下:
$allows = array("png", "jpg");
$filepath = 'upload/';
$imgname = $_FILES['file']['name'];
$tmp = $_FILES['file']['tmp_name'];
$extension = getExtension($imgname);
$destpath = $filepath . 'image.' . $extension;
function getExtension($filename) {
return pathinfo($filename, PATHINFO_EXTENSION);
}
if (in_array($extension, $allows)) {
move_uploaded_file($tmp, $destpath);
echo json_encode(array("path" => $destpath, "ret" => 0));
} else {
echo json_encode(array("ret" => -1));
}
如果你需要查看在線的demo,可以訪問:
當然上面的實現還是存在一定的局限性,對于qq、微信等軟件的截圖和快捷鍵print 等方式得到的截圖以及任意網頁的右擊復制圖片都能完美支持,但是,對于電腦本地圖片文件的復制沒辦法從剪切版直接獲取到,如果有哪位朋友有解決的方案請一定不吝賜教。
該實現方式在和上測試完美支持,但對于瀏覽器使用方式略有差別,只能在設置了屬性的元素身上才能觸發,要是遇到了IE就直接放棄吧,就仨字“不支持”,溜了溜了,多的就不說了,說多了都是淚