今日分享提升工作幸福感的知識點,希望大家不要錯過這些好文~
1、JS 文件 base64、File、Blob、ArrayBuffer 互轉
二進制互轉
- file對象轉base64
let?reader?=?new?FileReader();
?reader.readAsDataURL(file[0])
?console.log(reader)
- base64 轉成blob 上傳
function?dataURItoBlob(dataURI)?{??
????var?byteString?=?atob(dataURI.split(',')[1]);??
????var?mimeString?=?dataURI.split(',')[0].split(':')[1].split(';')[0];??
????var?ab?=?new?ArrayBuffer(byteString.length);??
????var?ia?=?new?Uint8Array(ab);??
????for?(var?i?=?0;?i?<?byteString.length;?i++)?{??
????????ia[i]?=?byteString.charCodeAt(i);??
????}??
????return?new?Blob([ab],?{type:?mimeString});??
}
- blob 轉成ArrayBuffer
let?blob?=?new?Blob([1,2,3,4])
let?reader?=?new?FileReader();
reader.onload?=?function(result)?{
????console.log(result);
}
reader.readAsArrayBuffer(blob);
- buffer 轉成blob
let?blob?=?new?Blob([buffer])
- base64 轉 file
const?base64ConvertFile?=?function?(urlData,?filename)?{?//?64轉file
??if?(typeof?urlData?!=?'string')?{
????this.$toast("urlData不是字符串")
????return;
??}
??var?arr?=?urlData.split(',')
??var?type?=?arr[0].match(/:(.*?);/)[1]
??var?fileExt?=?type.split('/')[1]
??var?bstr?=?atob(arr[1])
??var?n?=?bstr.length
??var?u8arr?=?new?Uint8Array(n)
??while?(n--)?{
????u8arr[n]?=?bstr.charCodeAt(n);
??}
??return?new?File([u8arr],?'filename.'?+?fileExt,?{
????type:?type
??});
}
2、10 個 HTML 文件上傳技巧
上傳文件功能可以說是項目經常出現的需求。從在社交媒體上上傳照片到在求職網站上發布簡歷,文件上傳無處不在。在本文中,我們將討論 HTML文件上傳支持的10種用法,希望對你有用。
1. 單文件上傳
我們可以將input 類型指定為file,以在Web應用程序中使用文件上傳功能。
<input?type="file"?id="file-uploader">
input filte 提供按鈕上傳一個或多個文件。默認情況下,它使用操作系統的本機文件瀏覽器上傳單個文件。成功上傳后,File API?使得可以使用簡單的 JS 代碼讀取File對象。要讀取File對象,我們需要監聽?change事件。
首先,通過id獲取文件上傳的實例:
const?fileUploader?=?document.getElementById('file-uploader');
然后添加一個change?事件偵聽器,以在上傳完成后讀取文件對象, 我們從event.target.files屬性獲取上傳的文件信息:
fileUploader.addEventListener('change',?(event)?=>?{
??const?files?=?event.target.files;
??console.log('files',?files);
});
在控制臺中觀察輸出結果,這里關注一下FileList數組和File對象,該對象具有有關上傳文件的所有元數據信息。
如果大家看到這里,有點激動,想手賤一下,可以 CodePen 玩玩,地址:
https://codepen.io/atapas/pen...
2. 多文件上傳
如果我們想上傳多個文件,需要在標簽上添加 multiple 屬性:
<input?type="file"?id="file-uploader"?multiple?/>
現在,我們可以上傳多個文件了,以前面事例為基礎,選擇多個文件上傳后,觀察一下控制臺的變化:
如果大家看到這里,有點激動,想手賤一下,可以 CodePen 玩玩,地址:
https://codepen.io/atapas/pen...
3.了解文件元數據
每當我們上傳文件時,File對象都有元數據信息,例如file name,size,last update time,type 等等。這些信息對于進一步的驗證和特殊處理很有用。
const fileUploader = document.getElementById('file-uploader');
//?聽更?change?件并讀取元數據
fileUploader.addEventListener('change',?(event)?=>?{
??//?獲取文件列表數組
??const?files?=?event.target.files;
??//?遍歷并獲取元數據
??for?(const?file?of?files)?{
????const?name?=?file.name;
????const?type?=?file.type???file.type:?'NA';
????const?size?=?file.size;
????const?lastModified?=?file.lastModified;
????console.log({?file,?name,?type,?size,?lastModified?});
??}
});
下面是單個文件上傳的輸出結果:
如果大家看到這里,有點激動,想手賤一下,可以 CodePen 玩玩,地址:
https://codepen.io/atapas/pen...
4.了解?accept?屬性
我們可以使用accept屬性來限制要上載的文件的類型,如果只想上傳的文件格式是 .jpg,.png 時,可以這么做:
<input?type="file"?id="file-uploader"?accept=".jpg,?.png"?multiple>
在上面的代碼中,只能選擇后綴是.jpg和.png的文件。
如果大家看到這里,有點激動,想手賤一下,可以 CodePen 玩玩,地址:
https://codepen.io/atapas/pen...
5. 管理文件內容
成功上傳文件后顯示文件內容,站在用戶的角度上,如果上傳之后,沒有一個預覽的,就很奇怪也不體貼。
我們可以使用FileReader對象將文件轉換為二進制字符串。然后添加load?事件偵聽器,以在成功上傳文件時獲取二進制字符串。
//?FileReader?實例
const?reader?=?new?FileReader();
fileUploader.addEventListener('change',?(event)?=>?{
??const?files?=?event.target.files;
??const?file?=?files[0];
??reader.readAsDataURL(file);
??reader.addEventListener('load',?(event)?=>?{
????const?img?=?document.createElement('img');
????imageGrid.appendChild(img);
????img.src?=?event.target.result;
????img.alt?=?file.name;
??});
});
如果大家看到這里,有點激動,想手賤一下,可以 CodePen 玩玩,地址:
https://codepen.io/atapas/pen...
文章后面還有五個技巧分享,分別是:
6.驗證文件大小
- 顯示文件上傳進度
- 怎么上傳目錄上傳?
- 拖拽上傳
- 使用objectURL處理文件
可以點擊標題鏈接,去原文章瀏覽全部技巧~
3、前端優秀實踐不完全指南
本文應該叫,Web 用戶體驗設計提升指南。
一個 Web 頁面,一個 APP,想讓別人用的爽,也就是所謂的良好的用戶體驗,我覺得他可能包括但不限于:
- 急速的打開速度
- 眼前一亮的 UI 設計
- 酷炫的動畫效果
- 豐富的個性化設置
- 便捷的操作b
- 貼心的細節
- 關注殘障人士,良好的可訪問性
- ...
所謂的用戶體驗設計,其實是一個比較虛的概念,是秉承著以用戶為中心的思想的一種設計手段,以用戶需求為目標而進行的設計。設計過程注重以用戶為中心,用戶體驗的概念從開發的最早期就開始進入整個流程,并貫穿始終。
良好的用戶體驗設計,是產品每一個環節共同努力的結果。
除去一些很難一蹴而就的,本文將就頁面展示、交互細節、可訪問性三個方面入手,羅列一些在實際的開發過程中,積攢的一些有益的經驗。通過本文,你將能收獲到:
- 了解到一些小細節是如何影響用戶體驗的
- 了解到如何在盡量小的開發改動下,提升頁面的用戶體驗
- 了解到一些優秀的交互設計細節
- 了解基本的無障礙功能及頁面可訪問性的含義
- 了解基本的提升頁面可訪問性的方法
4、13個頂級免費所見即所得文本編輯器工具
CKEditor
CKEditor擁有10多年的開發經驗,你可以完全放心此文本編輯器的質量。它支持70多種語言,我認為這是你網站的不錯選擇。它還可以運行在許多不同的瀏覽器上,并能很好地與大多數前端框架,如reat,vue,angular......你可以使用CDN直接嵌入到你的HTML頁面中......。目前它有兩個版本并行運行的CKEditor4和CKEditor5,根據不同的使用目的,你會選擇適合自己的編輯器。
Trumbowyg
Trumbowyg是針對HTML5優化的代碼編輯器,它支持大多數流行的瀏覽器,例如IE9 +,Firefox,Chrome等。據我所知,它包含用于文本編輯的所有工具,僅為20Kb,它輕巧,將幫助你的網站更流暢地運行。此外,它還具有其他支持插件來幫助你更好地工作,例如插入表情符號,其他國家/地區的支持語言,添加聲音,插入特殊字符...
TinyMCE
TinyMCE 5是一款編輯器,它能讓你靈活地編輯、添加或刪除本程序中的部分內容。除了基本的編輯器,那么我發現它還提供了很多支持,更好的用戶體驗,如添加評論,測試檢查路徑,提供優質的圖標和界面,檢查拼寫的內容...... 然而,這也是它的弱點,因為如果你想使用高級工具,你必須每月支付約25美元。
Quill
Quill是一個開放源代碼編輯器,因此可以將其用于所有類型的商業或非商業網站。它有很多功能,如添加鏈接,圖像,視頻或添加代碼片段的內容…關于Quill,我最喜歡的一點是它的簡單設置和顯示,可以在多設備屏幕上的所有現代的、響應迅速的web瀏覽器上顯示,還有使用它的常見問題的詳細說明。
Trix
Trix是一個開源的編輯器,可以讓你在Web中輕松地撰寫消息、寫評論、寫帖子......,并被良好編程的平板電腦使用。如果你只需要創建內容所需的功能,那么Trix同樣是不錯的選擇。
Jodit Editor 3
Jodit Editor 3是一個用純TypeScript編寫的開源github編輯器,不使用任何其他庫。它允許你以多種方式設置它,如通過npm、使用CDN......。我喜歡它的是,除了詳細的說明,還有一個程序,通過代碼讓我們自由選擇哪些工具附加到Jodit Editor。
Summernote
Summernote是GitHub上的開源編輯器,獲得了超過9K星。它是通過Bootstrap框架設計的,具有在你的網站上創建內容所需的所有功能。你只需要下載它的源文件css,js,再加上Bootstrap框架(也支持3、4兩個版本)就已經可以為你的網站服務了。
Editor.js
Editor.js是一個開源的塊狀編輯器,它不會像普通的編輯器那樣使用標簽HTML,將內容以JSON的形式輸出,使其更容易管理。它還支持通過使用API的插件,多虧了這一點,應該任何功能 任何開發者都可以為這個程序貢獻更多有趣和有用的插件。
MediumEditor
MediumEditor是Medium的內置的開放源代碼編輯器,用于人們博客。它僅包含編輯器所需的基本實用程序,因此僅約28kB,這將有助于你的網站得到優化。同時如果我們想要添加其他功能,為了優化編輯,MediumEditor還提供了額外的外部實用工具,定期更新。
Wysihtml
Wysihtml是一個由Voog團隊構建的開源編輯器。它功能齊全,可以幫助你輕松編輯文本,并且支持大多數現代屏幕瀏覽器的設備圖像。有很多工具我很喜歡它是自動轉換不合適的HTML標簽率,自動分析內容時從Word, PDF,顯示內容為HTML…
ContentTools
ContentTools是內置的開源編輯器,可幫助你輕松地一種方式編輯HTML內容。它提供了用于編輯內容的各種實用程序,你還可以輕松地將Message Institute和其他實用程序添加到程序中(請參閱脫機API部分)。我還發現了如何設置,添加或刪除程序中的函數的文章…都是非常細致的。
Froala
Froala是一個編輯器,可以很容易地為網站設置,并允許你根據預期用途打開廣泛的功能。由于它是用純JavaScript編寫的,因此你可以將其用于當今的大多數現代前端框架。它還提供了許多有用的工具,以及編輯圖像,添加或編輯視頻,添加圖標,管理面板等。但是,如果你要使用該工具用于商業目的,則必須購買許可證。
Redactor
Redactor是一款功能齊全的編輯器,具有精美而簡單的設計。超過9年的發展,包括很多支持插件,我想這是一個很好的產品。另外它對程序員在使用程序的過程中遇到的每一個常見問題都有極其詳細的實例。但是,它也有一個缺點,當你將其用于商業目的時必須購買許可證。
5、奇怪的知識——位掩碼
假設我們有一個權限系統,它通過 JSON 的方式記錄了某個用戶的權限開通情況(姑且假設權限集是 CURD):
const?permission?=?{
??create:?false,
??update:?false,
??read:?true,
??delete:?false,
}
如果我們把 false 寫成 0,true 寫成 1,那么這個 permisson 對象可以簡寫為?0b0010。
const?permission?=?{
??create:?false,
??update:?false,
??read:?true,
??delete:?false,
}
//?從左往右,依次為?create,?update,?read,?delete?所對應的值
const?permissionBinary?=?0b0010
對于 JSON 對象的權限集,如果我們要查看或者修改該用戶的某些權限,只需要通過形如 permission.craete 的普通對象操作即可。那么如果對于二進制形式的權限集,我們又應該如何進行查看或者修改的操作呢?接下來我們就開始使用奇怪的知識——位掩碼來進行了。
位掩碼
首先進行名詞解釋,什么是”位掩碼“。
位掩碼(BitMask),是”位(Bit)“和”掩碼(Mask)“的組合詞?!蔽弧爸复M制數據當中的二進制位,而”掩碼“指的是一串用于與目標數據進行按位操作的二進制數字。組合起來,就是”用一串二進制數字(掩碼)去操作另一串二進制數字“的意思。
明白了位掩碼的作用以后,我們就可以通過它來對權限集二進制數進行操作了。
1、查詢用戶是否擁有某個權限
已知用戶權限集二進制數為 permissionBinary = 0b0010。如果我想知道該用戶是否存在?update?這個權限,可以先給定一個位掩碼?mask = 0b1。
由于 update 位于右數第三項,所以只需要把位掩碼向左移動兩位,剩余位置補0。最后和權限集二進制數進行按位與運算即可得到結果。
最后算出來的 result 為?0b0000,使用 Boolean()?函數處理之即可得到 false 的結果,也就是說該用戶的 update 權限為 false。
//?從左往右,依次為?create,?update,?read,?delete?所對應的值
const?permissionBinary?=?0b0010
//?由于?update?位于右數第三位,因此只需要讓掩碼向左移動2位即可
const?mask?=?0b1?<<?2
const?result?=?permissionBinary?&?mask
Boolean(result)?//?false
2、修改用戶的某個權限
當我們明白了如何用位掩碼來查詢權限后,要修改對應的權限也就手到擒來了,無非就是換一種位運算。假設還是?update?權限,如果我想把它修改成?true,我們可以這么干:
只需要把按位與改為按位異或即可,代碼如下:
//?從左往右,依次為?create,?update,?read,?delete?所對應的值
const?permissionBinary?=?0b0010
//?由于?update?位于右數第三位,因此只需要讓掩碼向左移動2位即可
const?mask?=?0b1?<<?2
const?result?=?permissionBinary?^?mask
parseInt(result).toString(2)?//?0b0110
經過上面的內容,相信你已經基本掌握了位掩碼的知識,同時你肯定還有很多問號,比如說這么復雜又不好閱讀的代碼,真的有意義嗎?
臟數據記錄
前文例子中的權限系統僅有區區4個數據的處理,位掩碼技術顯得復雜又小題大做。那么有沒有什么場景是真的適合使用位掩碼的呢?臟數據記錄就是其中一個。
假設我們存在著一份原始數據,其值如下:
let?A?=?'a'
let?B?=?'b'
let?C?=?'c'
let?D?=?'d'
給定一個二進制數,從左往右分別對應著 A/B/C/D 的狀態:
let?O?=?0b0000?//?十進制?0
則數據一旦發生了修改,都可以用對應的比特位來表示
//?當且僅當?A?發生了修改
O?=?0b1000?//?十進制?8
//?當且僅當?B?發生了修改
O?=?0b0100?//?十進制?4
//?當且僅當?C?發生了修改
O?=?0b0010?//?十進制?2
//?當且僅當?D?發生了修改
O?=?0b0001?//?十進制?1
同理,當多個數據發生了修改時,則可以同時表示
//?當?A?和?B?發生了修改
O?=?0b1100?//?十進制?12
//?當?A/B/C?都發生了修改
O?=?0b1110?//?十進制?14
通過這個思路,應用排列組合的思想,可以很快知道只需要僅僅 4 個比特位,就可以表達 16 種數據變化的情況。由于二進制和十進制可以相互轉化,因此只需要區區 16 個十進制數,就可以完整地表達 A/B/C/D 這四個數據的變化情況,也就是臟數據追蹤。舉個例子,給定一個臟數據記錄 14,二進制轉換為?0b1110,因此表示 A/B/C 的數據被修改了。
Svelte 這個框架,就是通過這個思路來實現響應式的:
if?(?A?數據變了?)?{
??更新A對應的DOM節點
}
if?(?B?數據變了?)?{
??更新B對應的DOM節點
}
/**?轉化成偽代碼?**/
if?(?dirty?&?8?)?{?//?8?===?0b1000
??更新A對應的DOM節點
}
if?(?dirty?&?4?)?{?//?4?===?0b0100
??更新B對應的DOM節點
}
老鼠喝毒藥
除了用來做臟數據記錄以外,位掩碼也能夠用來處理經典的”老鼠喝毒藥“的問題。
有 1000 瓶水,其中有一瓶有毒,小白鼠只要嘗一點帶毒的水24小時后就會死亡,問至少要多少只小白鼠才能在24小時內鑒別出哪瓶水有毒?
我們簡化一下問題,假設只有 8 瓶水,其編號用二進制表示:
接著按照圖示的方式對水瓶的水進行混合,得到樣品 A/B/C/D,取4只老鼠編號為 a/b/c/d 分別喝下對應的水,得到如下的表格:
在 24 小時候,統計老鼠的死亡情況,匯總后可以得到表格和結果:
答案呼之欲出,由于 8 瓶水可以兌出 4 份樣品,因此只需要 4 只老鼠即可在 24 小時后確定到底哪一瓶水是有毒的?;氐筋}目,如果是 1000 瓶水,只需要知道第 1000 號的二進制數?0b1111101000即可。該二進制數一共有 10 個比特位,意味著 1000 瓶水可以兌出 10 份樣品,也就是說只需要 10 只老鼠,就可以完成測試任務。
尾聲
關于位掩碼技術的探索就到這里。相信在認真讀完這篇文章以后,大家心里已經建立起對位掩碼技術的概念。這是一種非常特別的問題解決思路,也許在未來的某一天你真的會用上它。