前端的能力邊界
當(dāng)前位置:點晴教程→知識管理交流
→『 技術(shù)文檔交流 』
了解一門語言能做什么很重要,既是學(xué)習(xí)的起點,也是應(yīng)用的落點。 JavaScript曾被認(rèn)為是“玩具”語言,誰都想不到,它后來把觸角伸到了服務(wù)端、工具鏈、App、桌面端、甚至是硬件和深度學(xué)習(xí)。 本文是此系列的最終篇,我們來探究一下,除了按照正確的語法和良好的組織去寫代碼,前端到底能做什么? 網(wǎng)絡(luò)請求動態(tài)數(shù)據(jù)是給網(wǎng)頁注入活力的重要因素,可以使得每天的內(nèi)容,每個人看到的內(nèi)容,都不同。 靠手寫是不行的,需要發(fā)起網(wǎng)絡(luò)請求。 在過去,請求任務(wù)由XMLHttpRequest來完成的,但在現(xiàn)代Web開發(fā)中,已經(jīng)被Fetch替代。 Fetch 前面提過,F(xiàn)etch是基于Promise的,它能以更簡潔清晰的方式實現(xiàn)異步,并且它支持流式響應(yīng)、請求取消和自動請求重發(fā)。 fetch()方法只有一個必須的參數(shù),即請求的url,其他參數(shù)按需配置,一個基本的POST請求寫法如下:
這段代碼較為完整地展現(xiàn)了POST請求的大概結(jié)構(gòu),請求返回后,可以通過返回的狀態(tài)碼,及各種不同數(shù)據(jù)的處理方法,來接收結(jié)果。 數(shù)據(jù)的處理方法有多種,除了text(),還有json()、blob()等,可根據(jù)返回數(shù)據(jù)的類型和需求進行選用。 Web Socket Fetch請求是由客戶端發(fā)起,服務(wù)端做響應(yīng)的單向通信,但有時候我們需要實現(xiàn)雙向通信,服務(wù)端主動向客戶端推送數(shù)據(jù),主流方案就是 Web Socket。 簡單使用:
EventSource API 這是一種比較新的API,但這兩年應(yīng)用很廣,大家看到的關(guān)于AI的信息交互,返回結(jié)果像打字機一樣輸出,起關(guān)鍵作用的就是它。 示例如下:
應(yīng)用比較簡單,但有一點需要說明,看起來它只支持get請求,無法傳參?如果需要傳參,怎么辦,有一個包可以幫助我們實現(xiàn)——@microsoft/fetch-event-source。 File上傳豐富的網(wǎng)頁功能,不僅讓用戶能輸入內(nèi)容,還要能上傳文件。 在早期,處理文件的唯一方式是把 File API 與 Blob API 就是為了讓W(xué)eb開發(fā)者更好地與文件交互而設(shè)計。它仍然以表單中的文件為基礎(chǔ),但增加了訪問文件信息的能力。 File類型 HTML5在DOM上為文件輸入元素添加了files集合,它包含一組File對象,表示被選中的文件。 每個File對象都有一些只讀屬性:name(文件名);size(文件大?。?;type(文件MIME類型);lastModifiedDate(文件最后修改時間) FileReader類型 File API還提供了FileReader類型,用于從文件中讀取數(shù)據(jù)。 每個FileReader會發(fā)布幾個事件,最有用的是progress、error和load。
某些情況下,可能需要讀取部分文件而不是整個文件。為此,F(xiàn)ile對象提供了一個名為slice()的方法。 Blob URL 有時候你會看到一個blob開頭的字符串來展示文件,它就是對象URL,也稱作Blob URL,是指引用存儲在File或Blob中數(shù)據(jù)的URL。 對象URL的優(yōu)點是不用把文件內(nèi)容讀取到JavaScript也可以使用文件。 要創(chuàng)建對象URL,可以使用window.URL.createObjectURL()方法并傳入File或Blob對象,這個函數(shù)返回的值是一個指向內(nèi)存中地址的字符串,因為這個字符串是URL,所以可以在DOM中直接使用。 拖拽上傳 除了點擊選擇上傳,將拖放API與File API結(jié)合使用,可實現(xiàn)拖拽上傳,在頁面上創(chuàng)建放置目標(biāo)后,把文件拖動到放置目標(biāo)。會觸發(fā)drop事件,被放置的文件可通過事件的event.dataTransfer.files屬性讀到。 圖形渲染圖形圖像是網(wǎng)頁不可缺少的部分,我們見到所有亮眼、炫酷的效果,都由它來完成,會給網(wǎng)頁吸引力加分。 最常見的img元素,但它只能用來展示圖片,想要實現(xiàn)更多,如圖形繪制、圖片處理,或者復(fù)雜動畫,就要用到Canvas。
上面這段代碼,繪制了一個“紅色矩形”,屬于圖形界的“Hello World”。 Canvas能做的事情,包括且不限于:畫線、各種形狀、文本、陰影、漸變、繪制圖像、填充圖案。 還有一項重要能力是獲取和操作圖像數(shù)據(jù)。
當(dāng)你拿到圖像的像素值,就可以為所欲為,當(dāng)然,需要具備一定的圖像知識。 這是2D繪制,還可以進行3D繪制,是現(xiàn)在很熱門的領(lǐng)域,同樣是用Canvas,但需要額外用到WebGL,WebGL并不屬于W3C標(biāo)準(zhǔn),且涉及OpenGL語言,超出了常規(guī)前端范疇,學(xué)習(xí)曲線比較陡峭,深入掌握的人少之又少,平時大家常用Three.js等工具庫做3D效果展示,這里不再贅述。 客戶端存儲通常,網(wǎng)頁端的數(shù)據(jù)來自兩處:接口獲取、代碼定義。 代碼中的需考慮維護性、靈活性,同時無法跨項目。 接口獲取的每次需要都得重新請求,消耗時間,特別是更新頻率很低時,會造成資源浪費。 于是,就有客戶端存儲這樣一種機制,將數(shù)據(jù)暫存在瀏覽器。 主要方案有:
富文本編輯怎樣實現(xiàn)一個可編輯的輸入框? 大部分人的第一反應(yīng)是input或者textarea,這兩種確實比較常用,但它們是單純用于“輸入”,別的干不了。 還有少部分可能會說contenteditable,能想起這個算不錯。 還有第三種,就是在頁面中嵌入一個iframe,給它的designMode屬性設(shè)置為“on”。 通常的做法像這樣:
這樣以來,被嵌入的那部分整個都可編輯。 但只是可編輯并不滿足需求,能交互才行,與富文本編輯器交互的方法有兩種: execCommand() 它的作用是,將字體變成“粗體、斜體”,或者改變文本背景,添加下劃線,插入“p、hr”等元素。
注意的點是,它用于修改內(nèi)嵌窗格(iframe)中富文本區(qū)域的外觀,如果想更加精細(xì)地控制當(dāng)前窗口的文本,要用第二種。 getSelection() 這個方法可以獲得富文本編輯器的選區(qū),其暴露在document和window對象上,返回表示當(dāng)前選中文本的Selection對象。 拿到對象后,其中有特別多的方法可用。直接看代碼:
上面這段代碼實現(xiàn)的是,將鼠標(biāo)劃過選中的文本背景設(shè)為黃色。 JavaScript API網(wǎng)頁的載體是瀏覽器,產(chǎn)品能實現(xiàn)什么,開發(fā)者能做什么,取決于瀏覽器。 如今的瀏覽器已經(jīng)成為集各種API于一身的“瑞士軍刀”,擇取一些功能性較強的API給大家。 Clipboard API 肯定有人和我一樣,得知這個API的時候,才知道在網(wǎng)頁端實現(xiàn)復(fù)制如此簡單。 其實不是到這個API才具備這個能力,但Clipboard API使得這件事變得簡單優(yōu)雅。 它通過readText() 和 writeText()方法實現(xiàn)讀取和寫入字符串。
同時,可以有剪貼板事件cut、copy、paste等進行監(jiān)聽。 跨上下文通信 跨文檔消息,也簡稱XDM(cross-document messaging),是一種在不同工作線程或不同源的頁面間傳遞信息的能力。 它的核心是postMessage()方法,接收到XDM消息后,window對象上會觸發(fā)message事件。 但最好只通過postMessage()發(fā)送字符串。如果需要傳遞結(jié)構(gòu)化數(shù)據(jù),最好先對該數(shù)據(jù)調(diào)用JSON.stringify(),通過postMessage()傳過去之后,再在onmessage事件處理程序中調(diào)用JSON.parse()。 除此之外,現(xiàn)在還比較常用的有 MessageChannel() 和 BroadcastChannel(),一個典型場景是,同域名下部署了幾個相互獨立的項目,要么一個內(nèi)嵌了另一個,要么在一個頁面上產(chǎn)生交互,另一個頁面需要接收狀態(tài)變化,這時候,相互通信的感知能力就很有用。 Observer API 開發(fā)者所期望的重要能力之一,就是“監(jiān)聽變化”,對變化的監(jiān)測會產(chǎn)生安全感。 DOM的變化在很長時間里是無法感知的,直到Observer API的出現(xiàn)。 現(xiàn)代瀏覽器支持的觀察者有如下幾個。 MutationObserver:監(jiān)聽DOM的修改,用于觀察整個文檔、DOM子樹或者一個元素,還能觀察元素屬性、子節(jié)點、文本等變化。 ResizeObserver:用于跟蹤DOM元素尺寸的變化,適用于響應(yīng)式Web設(shè)計或動態(tài)布局更新。 IntersectionObserver:監(jiān)聽DOM元素相對于指定視口或容器元素的可見性及位置。特別適合實現(xiàn)基于滾動的動畫、圖片懶加載、無窮滾動等性能優(yōu)化的實施。 以MutationObserver為例:
使用Observer API時,關(guān)鍵要處理好回調(diào)的性能,它可能會以驚人的頻率執(zhí)行,從而影響性能。一種方式是防抖,另一種方式是在不需要時把觀察者刪除。 Device API 現(xiàn)代網(wǎng)頁需要我們提供細(xì)致的個性化設(shè)計,而個性化離不開對網(wǎng)頁環(huán)境和設(shè)備的檢測,包括且不限于:設(shè)備類型、瀏覽器類型、操作系統(tǒng)等,這時就需要 Device API 的能力。 主要通過暴露在navigator對象上的一組屬性得到,比如:oscpu(系統(tǒng))、userAgent(瀏覽器)、orientation(屏幕朝向)等。 同時,還可通過Connection State 和 Networkinformation API 獲取到用戶的網(wǎng)絡(luò)連接情況,以便做出斷網(wǎng)或弱網(wǎng)處理,它們同樣暴露在navigator上,以及有相應(yīng)的 online、offline 事件可監(jiān)聽。 Page Visiblily API Web開發(fā)中有個常見問題,就是不知道用戶當(dāng)前在使用頁面,還是切到別的界面做其他事情去了。 最常見的場景就是視頻網(wǎng)站播廣告,你停在當(dāng)前頁面看,它才會播,否則就是浪費資源。 Page Visibily API就提供了這個能力。 document.visibilyState有三個值:visible(當(dāng)前可見)、hidden(不可見)、prerender(頁面在預(yù)渲染)。 其中不可見包括“標(biāo)簽頁切換”和“最小化”,同時,還可通過 visibilityChange 事件監(jiān)聽可視狀態(tài)的變化。 URL API 這個API的存在讓人覺得很貼心,因為你總會需要在URL中攜帶信息,獲取URL信息是特別常見的需求。 但在之前,需要通過拼接組件、正則匹配、字符串查找等一系列繁瑣操作,而URL API 使這件事變得簡單。 你只需要把URL傳進去,就能直接獲得一系列有價值的信息。
其中的參數(shù)更是能夠直接用過 URL的 searchParams 屬性輕易獲得和操作。
計時API 關(guān)于時間,多數(shù)人知道Date,但是Date的本意是日期,它更適用于日期相關(guān)處理,在時間精度上只能做到毫秒,對一些精度要求更高的場景無法滿足。 于是有了performance,它包含一批API,用在不同場景。 performance.now():從0開始計時,返回微妙精度的浮點值。 performance.mark():記錄自定義性能條目。 performance.getEntriesByType:度量當(dāng)前頁面加載速度,或者資源加載速度。 這些能力,可以輔助我們對用戶的真實體驗數(shù)據(jù)做收集和分析,以便做針對性的優(yōu)化。 工作者線程前端開發(fā)者常說:“JavaScript是單線程的”。所以經(jīng)常會面對一個問題—要做的事情太多,瀏覽器“忙不過來”,產(chǎn)生卡頓。 工作者線程,就是瀏覽器可以在原始頁面環(huán)境之外再分配一個完全獨立的二級子環(huán)境。這個子環(huán)境不能與依賴單線程交互的API(如DOM)互操作,但可以與父環(huán)境并行執(zhí)行代碼。 較為常見的就是“Web Worker”,通常會用來做文件的輸入輸出,進行密集型計算,處理大數(shù)據(jù)。 創(chuàng)建Web Woker的常見方式,是建立一個任務(wù)執(zhí)行腳本,然后把文件路徑給Worker構(gòu)造函數(shù)。
還有一種常見的稱作“Service Worker”(服務(wù)工作者線程),類似一個代理服務(wù)器,用于攔截外出請求和緩存響應(yīng)。可以讓網(wǎng)頁在沒有網(wǎng)絡(luò)連接的時候正常使用。 它最大的使用場景就是開發(fā)離線應(yīng)用,是開發(fā)PWA(漸進式Web應(yīng)用)的關(guān)鍵技術(shù)。 WebAssembly書中并未涉及WebAssembly,但這是前端開發(fā)在瀏覽器變得更強大繞不開的話題。 正常來說,圖片處理、音視頻處理、模型應(yīng)用等都是JavaScript不能辦到的,需要借助C++或者Python,但前端要做的話,有沒有辦法,答案就是WebAssembly。 比如,可以借助OpenCV.js、FFmpeg.js進行圖片和音視頻處理,可以借助TensorFlow.js、Transformer.js做模型訓(xùn)練和應(yīng)用。它們無一例外都用到了WebAssembly。 所以,WebAssembly的設(shè)計目標(biāo)就是為C/C++、Rust等語言提供高效的編譯目標(biāo),使其在瀏覽器中以接近原生性能運行。感興趣的朋友可進一步拓展學(xué)習(xí)。 ?轉(zhuǎn)自https://juejin.cn/post/7546564423894564879 該文章在 2025/9/10 10:01:32 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |