<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JS 文件互轉(zhuǎn)、10 個 HTML 文件上傳技巧、Web 用戶體驗設(shè)計提升指南、奇怪的知識——位掩碼 | 思否技術(shù)周刊

          共 14788字,需瀏覽 30分鐘

           ·

          2021-03-08 22:00

          值班編輯:袁鈺涵


          溫馨提示:本文包含大量外部鏈接,墻裂建議小伙伴們點擊 “閱讀原文“ 進(jìn)行閱讀。:)


          今日分享提升工作幸福感的知識點,希望大家不要錯過這些好文~




          1、JS 文件 base64、File、Blob、ArrayBuffer 互轉(zhuǎn)


          二進(jìn)制互轉(zhuǎn)


          1. file對象轉(zhuǎn)base64

           
             
          let reader = new FileReader();
           reader.readAsDataURL(file[0])
           console.log(reader)


          2. base64 轉(zhuǎn)成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});  
          }


          3. blob 轉(zhuǎn)成ArrayBuffer


             
          let blob = new Blob([1,2,3,4])
          let reader = new FileReader();
          reader.onload = function(result) {
              console.log(result);
          }
          reader.readAsArrayBuffer(blob);


          4. buffer 轉(zhuǎn)成blob


          let blob = new Blob([buffer])


          5. base64 轉(zhuǎn) file


          const base64ConvertFile = function (urlData, filename) { // 64轉(zhuǎn)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, {
              typetype
            });
          }


          文章地址:

          https://segmentfault.com/a/1190000039310309




          2、10 個 HTML 文件上傳技巧


          上傳文件功能可以說是項目經(jīng)常出現(xiàn)的需求。從在社交媒體上上傳照片到在求職網(wǎng)站上發(fā)布簡歷,文件上傳無處不在。在本文中,我們將討論 HTML文件上傳支持的10種用法,希望對你有用。


          1. 單文件上傳


          我們可以將input 類型指定為file,以在Web應(yīng)用程序中使用文件上傳功能。


             
          <input type="file" id="file-uploader">


          input filte 提供按鈕上傳一個或多個文件。默認(rèn)情況下,它使用操作系統(tǒng)的本機文件瀏覽器上傳單個文件。成功上傳后,F(xiàn)ile API 使得可以使用簡單的 JS 代碼讀取File對象。要讀取File對象,我們需要監(jiān)聽 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);
          });


          在控制臺中觀察輸出結(jié)果,這里關(guān)注一下FileList數(shù)組和File對象,該對象具有有關(guān)上傳文件的所有元數(shù)據(jù)信息。



          如果大家看到這里,有點激動,想手賤一下,可以 CodePen 玩玩,地址:

          https://codepen.io/atapas/pen/rNLOyRm


          2. 多文件上傳


          如果我們想上傳多個文件,需要在標(biāo)簽上添加 multiple 屬性:


             
          <input type="file" id="file-uploader" multiple />


          現(xiàn)在,我們可以上傳多個文件了,以前面事例為基礎(chǔ),選擇多個文件上傳后,觀察一下控制臺的變化:



          如果大家看到這里,有點激動,想手賤一下,可以 CodePen 玩玩,地址:

          https://codepen.io/atapas/pen/MWeamYp


          3.了解文件元數(shù)據(jù)


          每當(dāng)我們上傳文件時,F(xiàn)ile對象都有元數(shù)據(jù)信息,例如file name,size,last update time,type 等等。這些信息對于進(jìn)一步的驗證和特殊處理很有用。

          const fileUploader = document.getElementById('file-uploader');

          // 聽更 change 件并讀取元數(shù)據(jù)
          fileUploader.addEventListener('change', (event) => {
            // 獲取文件列表數(shù)組
            const files = event.target.files;

            // 遍歷并獲取元數(shù)據(jù)
            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 });
            }
          });


          下面是單個文件上傳的輸出結(jié)果:



          如果大家看到這里,有點激動,想手賤一下,可以 CodePen 玩玩,地址:

          https://codepen.io/atapas/pen/gOMaRJv


          4.了解 accept 屬性


          我們可以使用accept屬性來限制要上載的文件的類型,如果只想上傳的文件格式是 .jpg,.png 時,可以這么做:


             
          <input type="file" id="file-uploader" accept=".jpg, .png" multiple>


          在上面的代碼中,只能選擇后綴是.jpg和.png的文件。


          如果大家看到這里,有點激動,想手賤一下,可以 CodePen 玩玩,地址:

          https://codepen.io/atapas/pen/OJXymRP


          5. 管理文件內(nèi)容


          成功上傳文件后顯示文件內(nèi)容,站在用戶的角度上,如果上傳之后,沒有一個預(yù)覽的,就很奇怪也不體貼。


          我們可以使用FileReader對象將文件轉(zhuǎn)換為二進(jìn)制字符串。然后添加load 事件偵聽器,以在成功上傳文件時獲取二進(jìn)制字符串。


             
          // 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/zYBvdjZ


          文章后面還有五個技巧分享,分別是:


          6.驗證文件大小

          7. 顯示文件上傳進(jìn)度

          8. 怎么上傳目錄上傳?

          9. 拖拽上傳

          10. 使用objectURL處理文件


          可以點擊閱讀原文,去原文章瀏覽全部技巧~


          文章地址:

          https://segmentfault.com/a/1190000039312701




          3、前端優(yōu)秀實踐不完全指南


          本文應(yīng)該叫,Web 用戶體驗設(shè)計提升指南。


          一個 Web 頁面,一個 APP,想讓別人用的爽,也就是所謂的良好的用戶體驗,我覺得他可能包括但不限于:


          • 急速的打開速度
          • 眼前一亮的 UI 設(shè)計
          • 酷炫的動畫效果
          • 豐富的個性化設(shè)置
          • 便捷的操作b
          • 貼心的細(xì)節(jié)
          • 關(guān)注殘障人士,良好的可訪問性
          • ...

          所謂的用戶體驗設(shè)計,其實是一個比較虛的概念,是秉承著以用戶為中心的思想的一種設(shè)計手段,以用戶需求為目標(biāo)而進(jìn)行的設(shè)計。設(shè)計過程注重以用戶為中心,用戶體驗的概念從開發(fā)的最早期就開始進(jìn)入整個流程,并貫穿始終。

          良好的用戶體驗設(shè)計,是產(chǎn)品每一個環(huán)節(jié)共同努力的結(jié)果。

          除去一些很難一蹴而就的,本文將就頁面展示、交互細(xì)節(jié)、可訪問性三個方面入手,羅列一些在實際的開發(fā)過程中,積攢的一些有益的經(jīng)驗。通過本文,你將能收獲到:

          1. 了解到一些小細(xì)節(jié)是如何影響用戶體驗的
          2. 了解到如何在盡量小的開發(fā)改動下,提升頁面的用戶體驗
          3. 了解到一些優(yōu)秀的交互設(shè)計細(xì)節(jié)
          4. 了解基本的無障礙功能及頁面可訪問性的含義
          5. 了解基本的提升頁面可訪問性的方法

          文章地址:
          https://segmentfault.com/a/1190000039268059



          4、13個頂級免費所見即所得文本編輯器工具

          CKEditor


          CKEditor擁有10多年的開發(fā)經(jīng)驗,你可以完全放心此文本編輯器的質(zhì)量。它支持70多種語言,我認(rèn)為這是你網(wǎng)站的不錯選擇。它還可以運行在許多不同的瀏覽器上,并能很好地與大多數(shù)前端框架,如reat,vue,angular......你可以使用CDN直接嵌入到你的HTML頁面中......。目前它有兩個版本并行運行的CKEditor4和CKEditor5,根據(jù)不同的使用目的,你會選擇適合自己的編輯器。


          Trumbowyg


          Trumbowyg是針對HTML5優(yōu)化的代碼編輯器,它支持大多數(shù)流行的瀏覽器,例如IE9 +,F(xiàn)irefox,Chrome等。據(jù)我所知,它包含用于文本編輯的所有工具,僅為20Kb,它輕巧,將幫助你的網(wǎng)站更流暢地運行。此外,它還具有其他支持插件來幫助你更好地工作,例如插入表情符號,其他國家/地區(qū)的支持語言,添加聲音,插入特殊字符...


          TinyMCE


          TinyMCE 5是一款編輯器,它能讓你靈活地編輯、添加或刪除本程序中的部分內(nèi)容。除了基本的編輯器,那么我發(fā)現(xiàn)它還提供了很多支持,更好的用戶體驗,如添加評論,測試檢查路徑,提供優(yōu)質(zhì)的圖標(biāo)和界面,檢查拼寫的內(nèi)容...... 然而,這也是它的弱點,因為如果你想使用高級工具,你必須每月支付約25美元。


          Quill


          Quill是一個開放源代碼編輯器,因此可以將其用于所有類型的商業(yè)或非商業(yè)網(wǎng)站。它有很多功能,如添加鏈接,圖像,視頻或添加代碼片段的內(nèi)容…關(guān)于Quill,我最喜歡的一點是它的簡單設(shè)置和顯示,可以在多設(shè)備屏幕上的所有現(xiàn)代的、響應(yīng)迅速的web瀏覽器上顯示,還有使用它的常見問題的詳細(xì)說明。


          Trix


          Trix是一個開源的編輯器,可以讓你在Web中輕松地撰寫消息、寫評論、寫帖子......,并被良好編程的平板電腦使用。如果你只需要創(chuàng)建內(nèi)容所需的功能,那么Trix同樣是不錯的選擇。


          Jodit Editor 3


          Jodit Editor 3是一個用純TypeScript編寫的開源github編輯器,不使用任何其他庫。它允許你以多種方式設(shè)置它,如通過npm、使用CDN......。我喜歡它的是,除了詳細(xì)的說明,還有一個程序,通過代碼讓我們自由選擇哪些工具附加到Jodit Editor。


          Summernote


          Summernote是GitHub上的開源編輯器,獲得了超過9K星。它是通過Bootstrap框架設(shè)計的,具有在你的網(wǎng)站上創(chuàng)建內(nèi)容所需的所有功能。你只需要下載它的源文件css,js,再加上Bootstrap框架(也支持3、4兩個版本)就已經(jīng)可以為你的網(wǎng)站服務(wù)了。


          Editor.js


          Editor.js是一個開源的塊狀編輯器,它不會像普通的編輯器那樣使用標(biāo)簽HTML,將內(nèi)容以JSON的形式輸出,使其更容易管理。它還支持通過使用API的插件,多虧了這一點,應(yīng)該任何功能 任何開發(fā)者都可以為這個程序貢獻(xiàn)更多有趣和有用的插件。


          MediumEditor


          MediumEditor是Medium的內(nèi)置的開放源代碼編輯器,用于人們博客。它僅包含編輯器所需的基本實用程序,因此僅約28kB,這將有助于你的網(wǎng)站得到優(yōu)化。同時如果我們想要添加其他功能,為了優(yōu)化編輯,MediumEditor還提供了額外的外部實用工具,定期更新。


          Wysihtml


          Wysihtml是一個由Voog團(tuán)隊構(gòu)建的開源編輯器。它功能齊全,可以幫助你輕松編輯文本,并且支持大多數(shù)現(xiàn)代屏幕瀏覽器的設(shè)備圖像。有很多工具我很喜歡它是自動轉(zhuǎn)換不合適的HTML標(biāo)簽率,自動分析內(nèi)容時從Word, PDF,顯示內(nèi)容為HTML…


          ContentTools


          ContentTools是內(nèi)置的開源編輯器,可幫助你輕松地一種方式編輯HTML內(nèi)容。它提供了用于編輯內(nèi)容的各種實用程序,你還可以輕松地將Message Institute和其他實用程序添加到程序中(請參閱脫機API部分)。我還發(fā)現(xiàn)了如何設(shè)置,添加或刪除程序中的函數(shù)的文章…都是非常細(xì)致的。


          Froala


          Froala是一個編輯器,可以很容易地為網(wǎng)站設(shè)置,并允許你根據(jù)預(yù)期用途打開廣泛的功能。由于它是用純JavaScript編寫的,因此你可以將其用于當(dāng)今的大多數(shù)現(xiàn)代前端框架。它還提供了許多有用的工具,以及編輯圖像,添加或編輯視頻,添加圖標(biāo),管理面板等。但是,如果你要使用該工具用于商業(yè)目的,則必須購買許可證。


          Redactor


          Redactor是一款功能齊全的編輯器,具有精美而簡單的設(shè)計。超過9年的發(fā)展,包括很多支持插件,我想這是一個很好的產(chǎn)品。另外它對程序員在使用程序的過程中遇到的每一個常見問題都有極其詳細(xì)的實例。但是,它也有一個缺點,當(dāng)你將其用于商業(yè)目的時必須購買許可證。


          文章地址:
          https://segmentfault.com/a/1190000039349270



          5、奇怪的知識——位掩碼

          假設(shè)我們有一個權(quán)限系統(tǒng),它通過 JSON 的方式記錄了某個用戶的權(quán)限開通情況(姑且假設(shè)權(quán)限集是 CURD):

             
          const permission = {
            create: false,
            update: false,
            readtrue,
            delete: false,
          }

          如果我們把 false 寫成 0,true 寫成 1,那么這個 permisson 對象可以簡寫為 0b0010。
             

          const permission = {
            create: false,
            update: false,
            readtrue,
            delete: false,
          }

          // 從左往右,依次為 create, update, read, delete 所對應(yīng)的值
          const permissionBinary = 0b0010

          對于 JSON 對象的權(quán)限集,如果我們要查看或者修改該用戶的某些權(quán)限,只需要通過形如 permission.craete 的普通對象操作即可。那么如果對于二進(jìn)制形式的權(quán)限集,我們又應(yīng)該如何進(jìn)行查看或者修改的操作呢?接下來我們就開始使用奇怪的知識——位掩碼來進(jìn)行了。

          位掩碼


          首先進(jìn)行名詞解釋,什么是”位掩碼“。

          位掩碼(BitMask),是”位(Bit)“和”掩碼(Mask)“的組合詞。”位“指代著二進(jìn)制數(shù)據(jù)當(dāng)中的二進(jìn)制位,而”掩碼“指的是一串用于與目標(biāo)數(shù)據(jù)進(jìn)行按位操作的二進(jìn)制數(shù)字。組合起來,就是”用一串二進(jìn)制數(shù)字(掩碼)去操作另一串二進(jìn)制數(shù)字“的意思。

          明白了位掩碼的作用以后,我們就可以通過它來對權(quán)限集二進(jìn)制數(shù)進(jìn)行操作了。

          1、查詢用戶是否擁有某個權(quán)限


          已知用戶權(quán)限集二進(jìn)制數(shù)為 permissionBinary = 0b0010。如果我想知道該用戶是否存在 update 這個權(quán)限,可以先給定一個位掩碼 mask = 0b1。


          由于 update 位于右數(shù)第三項,所以只需要把位掩碼向左移動兩位,剩余位置補0。最后和權(quán)限集二進(jìn)制數(shù)進(jìn)行按位與運算即可得到結(jié)果。


          最后算出來的 result 為 0b0000,使用 Boolean() 函數(shù)處理之即可得到 false 的結(jié)果,也就是說該用戶的 update 權(quán)限為 false。

             
          // 從左往右,依次為 create, update, read, delete 所對應(yīng)的值
          const permissionBinary = 0b0010

          // 由于 update 位于右數(shù)第三位,因此只需要讓掩碼向左移動2位即可
          const mask = 0b1 << 2

          const result = permissionBinary & mask

          Boolean(result) // false

          2、修改用戶的某個權(quán)限


          當(dāng)我們明白了如何用位掩碼來查詢權(quán)限后,要修改對應(yīng)的權(quán)限也就手到擒來了,無非就是換一種位運算。假設(shè)還是 update 權(quán)限,如果我想把它修改成 true,我們可以這么干:


          只需要把按位與改為按位異或即可,代碼如下:

             
          // 從左往右,依次為 create, update, read, delete 所對應(yīng)的值
          const permissionBinary = 0b0010

          // 由于 update 位于右數(shù)第三位,因此只需要讓掩碼向左移動2位即可
          const mask = 0b1 << 2

          const result = permissionBinary ^ mask

          parseInt(result).toString(2) // 0b0110



          經(jīng)過上面的內(nèi)容,相信你已經(jīng)基本掌握了位掩碼的知識,同時你肯定還有很多問號,比如說這么復(fù)雜又不好閱讀的代碼,真的有意義嗎?

          臟數(shù)據(jù)記錄


          前文例子中的權(quán)限系統(tǒng)僅有區(qū)區(qū)4個數(shù)據(jù)的處理,位掩碼技術(shù)顯得復(fù)雜又小題大做。那么有沒有什么場景是真的適合使用位掩碼的呢?臟數(shù)據(jù)記錄就是其中一個。

          假設(shè)我們存在著一份原始數(shù)據(jù),其值如下:

             
          let A = 'a'
          let B = 'b'
          let C = 'c'
          let D = 'd'

          給定一個二進(jìn)制數(shù),從左往右分別對應(yīng)著 A/B/C/D 的狀態(tài):

             
          let O = 0b0000 // 十進(jìn)制 0

          則數(shù)據(jù)一旦發(fā)生了修改,都可以用對應(yīng)的比特位來表示
             

          // 當(dāng)且僅當(dāng) A 發(fā)生了修改
          O = 0b1000 // 十進(jìn)制 8

          // 當(dāng)且僅當(dāng) B 發(fā)生了修改
          O = 0b0100 // 十進(jìn)制 4

          // 當(dāng)且僅當(dāng) C 發(fā)生了修改
          O = 0b0010 // 十進(jìn)制 2

          // 當(dāng)且僅當(dāng) D 發(fā)生了修改
          O = 0b0001 // 十進(jìn)制 1

          同理,當(dāng)多個數(shù)據(jù)發(fā)生了修改時,則可以同時表示
             

          // 當(dāng) A 和 B 發(fā)生了修改
          O = 0b1100 // 十進(jìn)制 12

          // 當(dāng) A/B/C 都發(fā)生了修改
          O = 0b1110 // 十進(jìn)制 14

          通過這個思路,應(yīng)用排列組合的思想,可以很快知道只需要僅僅 4 個比特位,就可以表達(dá) 16 種數(shù)據(jù)變化的情況。由于二進(jìn)制和十進(jìn)制可以相互轉(zhuǎn)化,因此只需要區(qū)區(qū) 16 個十進(jìn)制數(shù),就可以完整地表達(dá) A/B/C/D 這四個數(shù)據(jù)的變化情況,也就是臟數(shù)據(jù)追蹤。舉個例子,給定一個臟數(shù)據(jù)記錄 14,二進(jìn)制轉(zhuǎn)換為 0b1110,因此表示 A/B/C 的數(shù)據(jù)被修改了。

          Svelte 這個框架,就是通過這個思路來實現(xiàn)響應(yīng)式的:

             
          if ( A 數(shù)據(jù)變了 ) {
            更新A對應(yīng)的DOM節(jié)點
          }
          if ( B 數(shù)據(jù)變了 ) {
            更新B對應(yīng)的DOM節(jié)點
          }

          /** 轉(zhuǎn)化成偽代碼 **/

          if ( dirty & 8 ) { // 8 === 0b1000
            更新A對應(yīng)的DOM節(jié)點
          }
          if ( dirty & 4 ) { // 4 === 0b0100
            更新B對應(yīng)的DOM節(jié)點
          }

          老鼠喝毒藥


          除了用來做臟數(shù)據(jù)記錄以外,位掩碼也能夠用來處理經(jīng)典的”老鼠喝毒藥“的問題。

          有 1000 瓶水,其中有一瓶有毒,小白鼠只要嘗一點帶毒的水24小時后就會死亡,問至少要多少只小白鼠才能在24小時內(nèi)鑒別出哪瓶水有毒?

          我們簡化一下問題,假設(shè)只有 8 瓶水,其編號用二進(jìn)制表示:


          接著按照圖示的方式對水瓶的水進(jìn)行混合,得到樣品 A/B/C/D,取4只老鼠編號為 a/b/c/d 分別喝下對應(yīng)的水,得到如下的表格:


          在 24 小時候,統(tǒng)計老鼠的死亡情況,匯總后可以得到表格和結(jié)果:


          答案呼之欲出,由于 8 瓶水可以兌出 4 份樣品,因此只需要 4 只老鼠即可在 24 小時后確定到底哪一瓶水是有毒的?;氐筋}目,如果是 1000 瓶水,只需要知道第 1000 號的二進(jìn)制數(shù) 0b1111101000即可。該二進(jìn)制數(shù)一共有 10 個比特位,意味著 1000 瓶水可以兌出 10 份樣品,也就是說只需要 10 只老鼠,就可以完成測試任務(wù)。

          尾聲


          關(guān)于位掩碼技術(shù)的探索就到這里。相信在認(rèn)真讀完這篇文章以后,大家心里已經(jīng)建立起對位掩碼技術(shù)的概念。這是一種非常特別的問題解決思路,也許在未來的某一天你真的會用上它。

          文章地址:
          https://segmentfault.com/a/1190000039239875



          - END -

          瀏覽 15
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天堂sv在线播放 | 中文人妻无码一区二区三区久久 | se亚洲| 欧美亚州15p | 亚洲欧美福利导航 |