整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          1分鐘,徹底弄懂瀏覽器緩存策略

          者:kevinylzhao,騰訊音樂前端開發工程師

          瀏覽器緩存策略對于前端開發同學來說不陌生,大家都有一定的了解,但如果沒有系統的歸納總結,可能三言兩語很難說明白,甚至說錯,尤其在面試過程中感觸頗深,很多候選人對這類基礎知識竟然都是一知半解,說出幾個概念就沒了,所以重新歸納總結下,溫故而知新。


          Web 緩存介紹

          • Web 緩存是指一個 Web 資源(如 html 頁面,圖片,js,數據等)存在于 Web 服務器和客戶端(瀏覽器)之間的副本。
          • 緩存會根據進來的請求保存輸出內容的副本;當下一個請求來到的時候,如果是相同的 URL,緩存會根據緩存機制決定是直接使用副本響應訪問請求,還是向源服務器再次發送請求。

          Web 緩存的好處

          • 減少網絡延遲,加快頁面打開速度
          • 減少網絡帶寬消耗
          • 降低服務器壓力
          • ...

          HTTP 的緩存機制

          簡化的流程如下

          根據什么規則緩存

          1. 新鮮度(過期機制):也就是緩存副本有效期。一個緩存副本必須滿足以下條件,瀏覽器會認為它是有效的,足夠新的:
          • 含有完整的過期時間控制頭信息(HTTP 協議報頭),并且仍在有效期內;
          • 瀏覽器已經使用過這個緩存副本,并且在一個會話中已經檢查過新鮮度;
          1. 校驗值(驗證機制):服務器返回資源的時候有時在控制頭信息帶上這個資源的實體標簽 Etag(Entity Tag),它可以用來作為瀏覽器再次請求過程的校驗標識。如果發現校驗標識不匹配,說明資源已經被修改或過期,瀏覽器需求重新獲取資源內容。

          HTTP 緩存的兩個階段

          瀏覽器緩存一般分為兩類:強緩存(也稱本地緩存)和協商緩存(也稱弱緩存)。

          本地緩存階段

          瀏覽器發送請求前,會先去緩存里查看是否命中強緩存,如果命中,則直接從緩存中讀取資源,不會發送請求到服務器。否則,進入下一步。

          協商緩存階段

          當強緩存沒有命中時,瀏覽器一定會向服務器發起請求。服務器會根據 Request Header 中的一些字段來判斷是否命中協商緩存。如果命中,服務器會返回 304 響應,但是不會攜帶任何響應實體,只是告訴瀏覽器可以直接從瀏覽器緩存中獲取這個資源。如果本地緩存和協商緩存都沒有命中,則從直接從服務器加載資源。

          啟用&關閉緩存

          按照本地緩存階段和協商緩存階段分類:

          1. 使用 HTML Meta 標簽    Web 開發者可以在 HTML 頁面的節點中加入標簽,如下:

          上述代碼的作用是告訴瀏覽器當前頁面不被緩存,事實上這種禁用緩存的形式用處很有限:

          a. 僅有 IE 才能識別這段 meta 標簽含義,其它主流瀏覽器僅識別“Cache-Control: no-store”的 meta 標簽。

          b. 在 IE 中識別到該 meta 標簽含義,并不一定會在請求字段加上 Pragma,但的確會讓當前頁面每次都發新請求(僅限頁面,頁面上的資源則不受影響)。

          1. 使用緩存有關的 HTTP 消息報頭 這里需要了解 HTTP 的基礎知識。一個 URI 的完整 HTTP 協議交互過程是由 HTTP 請求和 HTTP 響應組成的。有關 HTTP 詳細內容可參考《Hypertext Transfer Protocol — HTTP/1.1》、《HTTP 權威指南》等。

          在 HTTP 請求和響應的消息報頭中,常見的與緩存有關的消息報頭有:

          上圖中只是常用的消息報頭,下面來看下不同字段之間的關系和區別:

          1. Cache-Control 與 Expires
          2. Cache-Control:HTTP1.1 提出的特性,為了彌補 Expires 缺陷加入的,提供了更精確細致的緩存功能。詳細了解詳細看幾個常見的指令:_ max-age:功能和 Expires 類似,但是后面跟一個以“秒”為單位的相對時間,來供瀏覽器計算過期時間。_ no-cache:提供了過期驗證機制。(在 Chrome 的 devtools 中勾選 Disable cache 選項,發送的請求會去掉 If-Modified-Since 這個 Header。同時設置 Cache-Control:no-cache Pragma:no-cache,每次請求均為 200)
            • no-store:表示當前請求資源禁用緩存;
            • public:表示緩存的版本可以被代理服務器或者其他中間服務器識別;
            • private:表示只有用戶自己的瀏覽器能夠進行緩存,公共的代理服務器不允許緩存。
          • Expires:HTTP1.0 的特性,標識該資源過期的時間點,它是一個絕對值,格林威治時間(Greenwich Mean Time, GMT),即在這個時間點之后,緩存的資源過期;優先級:Cache-Control 優先級高于 Expires,為了兼容,通常兩個頭部同時設置;瀏覽器默認行為:其實就算 Response Header 中沒有設置 Cache-Control 和 Expires,瀏覽器仍然會緩存某些資源,這是瀏覽器的默認行為,是為了提升性能進行的優化,每個瀏覽器的行為可能不一致,有些瀏覽器甚至沒有這樣的優化。
          1. Last-Modified 與 ETag
          2. Last-Modified(Response Header)與 If-Modified-Since(Request Header)是一對報文頭,屬于 http 1.0。If-Modified-Since 是一個請求首部字段,并且只能用在 GET 或者 HEAD 請求中。Last-Modified 是一個響應首部字段,包含服務器認定的資源作出修改的日期及時間。當帶著 If-Modified-Since 頭訪問服務器請求資源時,服務器會檢查 Last-Modified,如果 Last-Modified 的時間早于或等于 If-Modified-Since 則會返回一個不帶主體的 304 響應,否則將重新返回資源。(注意:在 Chrome 的 devtools 中勾選 Disable cache 選項后,發送的請求會去掉 If-Modified-Since 這個 Header。)
          • ETag 與 If-None-Match 是一對報文頭,屬于 http 1.1。ETag 是一個響應首部字段,它是根據實體內容生成的一段 hash 字符串,標識資源的狀態,由服務端產生。If-None-Match 是一個條件式的請求首部。如果請求資源時在請求首部加上這個字段,值為之前服務器端返回的資源上的 ETag,則當且僅當服務器上沒有任何資源的 ETag 屬性值與這個首部中列出的時候,服務器才會返回帶有所請求資源實體的 200 響應,否則服務器會返回不帶實體的 304 響應。
          • ETag 能解決什么問題?

          a. Last-Modified 標注的最后修改只能精確到秒級,如果某些文件在 1 秒鐘以內,被修改多次的話,它將不能準確標注文件的新鮮度;

          b. 某些文件也許會周期性的更改,但是它的內容并不改變(僅僅改變的修改時間),但 Last-Modified 卻改變了,導致文件沒法使用緩存;

          c. 有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形。

          • 優先級:ETag 優先級比 Last-Modified 高,同時存在時會以 ETag 為準。
          緩存位置

          瀏覽器可以在內存、硬盤中開辟一個空間用于保存請求資源副本。我們經常調試時在 DevTools Network 里看到 Memory Cache(內存緩存)和 Disk Cache(硬盤緩存),指的就是緩存所在的位置。請求一個資源時,會按照優先級(Service Worker -> Memory Cache -> Disk Cache -> Push Cache)依次查找緩存,如果命中則使用緩存,否則發起請求。這里先介紹 Memory Cache 和 Disk Cache。

          200 from memory cache

          表示不訪問服務器,直接從內存中讀取緩存。因為緩存的資源保存在內存中,所以讀取速度較快,但是關閉進程后,緩存資源也會隨之銷毀,一般來說,系統不會給內存分配較大的容量,因此內存緩存一般用于存儲較小文件。同時內存緩存在有時效性要求的場景下也很有用(比如瀏覽器的隱私模式)。

          200 from disk cache

          表示不訪問服務器,直接從硬盤中讀取緩存。與內存相比,硬盤的讀取速度相對較慢,但硬盤緩存持續的時間更長,關閉進程之后,緩存的資源仍然存在。由于硬盤的容量較大,因此一般用于存儲大文件。

          下圖可清晰看出差別:

          200 from prefetch cache

          在 preload 或 prefetch 的資源加載時,兩者也是均存儲在 http cache,當資源加載完成后,如果資源是可以被緩存的,那么其被存儲在 http cache 中等待后續使用;如果資源不可被緩存,那么其在被使用前均存儲在 memory cache。

          CDN Cache

          以騰訊 CDN 為例:X-Cache-Lookup:Hit From MemCache 表示命中 CDN 節點的內存;X-Cache-Lookup:Hit From Disktank 表示命中 CDN 節點的磁盤;X-Cache-Lookup:Hit From Upstream 表示沒有命中 CDN。

          整體流程

          從上圖能感受到整個流程,比如常見兩種刷新場景:

          • 當 F5 刷新網頁時,跳過強緩存,但是會檢查協商緩存;
          • 當 Ctrl + F5 強制刷新頁面時,直接從服務器加載,跳過強緩存和協商緩存

          其他 Web 緩存策略

          IndexDB

          IndexedDB 就是瀏覽器提供的本地數據庫,能夠在客戶端存儲可觀數量的結構化數據,并且在這些數據上使用索引進行高性能檢索的 API。

          異步 API 方法調用完后會立即返回,而不會阻塞調用線程。要異步訪問數據庫,要調用 window 對象 indexedDB 屬性的 open() 方法。該方法返回一個 IDBRequest 對象 (IDBOpenDBRequest);異步操作通過在 IDBRequest 對象上觸發事件來和調用程序進行通信。

          常用異步 API 如下:

          在 16 年曾基于 IndexDB 做過一整套緩存策略,有不錯的優化效果:

          Service Worker

          SW 從 2014 年提出的草案到現在已經發展很成熟了,基于 SW 做離線緩存,讓用戶能夠進行離線體驗,消息推送體驗,離線緩存能力涉及到 Cache 和 CacheStorage 的概念,篇幅有限,不展開了。

          LocalStorage

          localStorage 屬性允許你訪問一個 Document 源(origin)的對象 Storage 用于存儲當前源的數據,除非用戶人為清除(調用 localStorage api 或者清除瀏覽器數據), 否則存儲在 localStorage 的數據將被長期保留。

          SessionStorage

          sessionStorage 屬性允許你訪問一個 session Storage 對象,用于存儲當前會話的數據,存儲在 sessionStorage 里面的數據在頁面會話結束時會被清除。頁面會話在瀏覽器打開期間一直保持,并且重新加載或恢復頁面仍會保持原來的頁面會話。

          定義最優緩存策略

          • 使用一致的網址:如果您在不同的網址上提供相同的內容,將會多次獲取和存儲該內容。注意:URL 區分大小寫!
          • 確定中繼緩存可以緩存哪些資源:對所有用戶的響應完全相同的資源很適合由 CDN 或其他中繼緩存進行緩存;
          • 確定每個資源的最優緩存周期:不同的資源可能有不同的更新要求。審查并確定每個資源適合的 max-age;
          • 確定網站的最佳緩存層級:對 HTML 文檔組合使用包含內容特征碼的資源網址以及短時間或 no-cache 的生命周期,可以控制客戶端獲取更新的速度;
          • 更新最小化:有些資源的更新比其他資源頻繁。如果資源的特定部分(例如 JS 函數或一組 CSS 樣式)會經常更新,應考慮將其代碼作為單獨的文件提供。這樣,每次獲取更新時,剩余內容(例如不會頻繁更新的庫代碼)可以從緩存中獲取,確保下載的內容量最少;
          • 確保服務器配置或移除 ETag:因為 Etag 跟服務器配置有關,每臺服務器的 Etag 都是不同的;
          • 善用 HTML5 的緩存機制:合理設計啟用 LocalStorage、SessionStorage、IndexDB、SW 等存儲,會給頁面性能帶來明顯提升;
          • 結合 Native 的強大存儲能力:善于利用客戶端能力,定制合適的緩存機制,打造極致體驗。

          結語

          通過了解瀏覽器各種緩存機制和存儲能力特點,結合業務制定合適的緩存策略,善用緩存是基本功,可以用于時常審查負責的業務,可能就會發現個別業務并沒有運用到位,共勉。

          家好,我是 Echa。

          今天來分享 50 個超實用的 Chrome 瀏覽器擴展!

          JSON

          1. JSON Viewer Pro

          JSON Viewer Pro 用于可視化JSON文件。其核心功能包括:

          • 支持將JSON數據進行格式化,并使用屬性或者圖表進行展示;
          • 使用面包屑深入遍歷 JSON 屬性;
          • 在輸入區寫入自定義 JSON;
          • 導入本地 JSON 文件;
          • 使用上下文菜單下載 JSON 文件;
          • 網址過濾器;
          • 改變主題;
          • 自定義 CSS ;
          • 復制屬性和值;

          輸入界面如下:

          格式化之后:

          2. JSONVue

          JSONVue 是一個JSON數據查看器,主要用來格式化JSON數據:

          網站技術

          3. Library Sniffer

          Library Sniffer 是一款給開發者使用的工具,能夠探測當前網頁所使用的類庫、框架和服務器環境,為開發者提供了方便。

          4. Wappalyzer

          Wappalyzer 擴展可以用來識別網站背后的底層技術。通過此擴展,可以了解特定應用程序是否是用 React、Vue、Angular、PHP等編寫的。還可以訪問有關 Web 服務器、編程語言、框架、內容管理系統、分析的信息工具、數據庫等。

          5. WhatRuns

          WhatRuns 擴展程序只需單擊一下即可找到任何網站上使用的技術。

          開發調試

          6. PerfectPixel by WellDoneCode

          使用PerfectPixel插件可以將設計圖加載至網頁中,與已成型的網頁進行重疊對比,以幫助開發和設計人員規范網頁像素精度。這是一款可以優化前端頁面顯示的Chrome插件。

          7. Clear Cache

          可以使用此擴展程序快速清除緩存,無需任何確認對話框、彈出窗口等。可以在選項頁面上自定義要清除的數據和數量,包括:應用程序緩存、緩存、Cookie、下載、文件系統、表單數據、歷史記錄、索引數據庫、本地存儲、插件數據、密碼和 WebSQL。

          8. VisBug

          VisBug 是一個使用 JavaScript 構建的開源網頁設計調試工具,它可以讓用戶使用點擊式和拖放式界面來查看網站的元素。

          9. Debug CSS

          Debug CSS 是一個幫助調試CSS的插件。他可以顯示出頁面元素的輪播,按住Ctrl,并將鼠標懸浮在元素上,即可查看其信息:

          10. CSS Viewer

          CSS Viewer 是一款適用于 Web 開發人員的高效 Chrome 擴展。顧名思義,CSS 查看器可以顯示將鼠標懸停在任何網頁上的元素的 CSS 屬性。

          11. EditThisCookie

          EditThisCookie 是一個 cookie 管理器。可以添加,刪除,編輯,搜索,鎖定和屏蔽cookies。

          12. React Developer Tools

          React Developer Tools 是開源 JavaScript 庫 React 的 Chrome DevTools 擴展。它允許我們在 Chrome 開發者工具中檢查 React 組件層次結構。安裝此插件之后,將在 Chrome DevTools 中獲得兩個新選項卡:"?? Components" 和 "?? Profiler":

          • Components 選項卡顯示了在頁面上呈現的根 React 組件,以及它們最終呈現的子組件;
          • Profiler 選項卡用來記錄性能信息。

          13. Vue.js devtools

          Vue.js devtools 是一款基于chrome瀏覽器的用于調試Vue.js應用程序的插件,可以使得開發人員大大提高調試效率。支持用戶對DOM結構數據結構進行解析和調試功能。

          14. Augury

          Augury 可以幫助開發人員在 Google Chrome 瀏覽器中調試和分析 Angular 應用程序。

          15. Firebug Lite for Google Chrome

          Firebug Lite是火狐瀏覽器中著名的開發者工具firebug插件移植到Chrome中的插件,在Chrome中安裝了Firebug Lite插件以后,開發人員可以像在火狐瀏覽器中使用firebug一樣熟悉的方式來調試網頁內容,其包含了基本的HTML、CSS以及Javascript的調試功能,用于幫助網頁前端開發工程師快速地調試網頁,以便及時地找到網頁中的BUG并及時修復。

          16. HTML Validator

          HTML Validator 在 Chrome 的開發者工具中添加了 HTML Validator。HTML 頁面的錯誤數通過瀏覽器狀態欄中的圖標顯示,詳細信息可以在瀏覽器的開發者工具中查看。

          17. Web Developer

          Web Developer 擴展為帶有各種 Web 開發工具的瀏覽器添加了一個工具欄按鈕。該擴展適用于 Chrome 和 Firefox,并且可以在這些瀏覽器支持的任何平臺上運行,包括 Windows、macOS 和 Linux。

          18. Requestly

          Requestly 是一款Chrome和Firefox瀏覽器插件,提供URL轉發、修改HTTP請求和結果、插入腳本等功能。

          19. Window Resizer

          Window Resizer 主要用來調整瀏覽器窗口的大小以模擬各種屏幕分辨率。

          20. Responsive Viewer

          Responsive Viewer 是在一個視圖中顯示多個屏幕的 Chrome 擴展程序。該擴展將幫助前端開發人員在開發響應式網站/應用程序時測試多個屏幕。

          21. Moesif Origin & CORS Changer

          此插件允許直接從瀏覽器發送跨域請求,而不會收到跨域錯誤。可以使用此插件覆蓋 Request Origin 標頭,并將 Access-Control-Allow-Origin 設置為 *.

          22. ColorPick Eyedropper

          ColorPick Eyedropper 是一個放大的吸管和顏色選擇器工具,可讓從網頁等中選擇顏色值。

          23. CSSPeeper

          CSS Peeper 用于檢查和復制元素樣式的優秀工具,使用 CSSPeeper 可以將鼠標懸停在網頁中的任何元素上,然后單擊鼠標即可復制元素的樣式。

          24. Dimensions

          Dimensions是一款能幫助使用者對網頁上各種元素屬性之間的距離進行測量的Chrome頁面元素測量插件,該插件在點擊啟動插件圖標后,可以對頁面中圖像、輸入字段、按鈕以及視頻等頁面元素之間上下左右的方位尺寸進行測量,同時還可以通過使用快捷鍵來快速啟用或關閉該插件的功能,簡單實用。

          25. Site Palette

          Site Palette 用于生成調色板。設計師和前端開發人員必備的工具。可以通過這款插件輕松獲取網站的配色方案。

          26. ColorZilla

          ColorZilla 是一款功能強大地提取網頁色彩的工具;也是個快速的對顏色進行調節的Chrome插件,許多的用戶將這款軟件稱呼為顏色吸取插件,它提取的顏色是非常的多樣化,還可生產css顏色的代碼等。

          • 吸管器-獲取頁面上任何像素或區域的顏色;
          • 一個先進的顏色選擇器類似于可以在Photoshop和Paint Shop Pro中找到的;
          • 網頁顏色分析器-分析任何網頁上的DOM元素顏色,找到相應的元素;
          • 終極CSS梯度發生器;
          • 調色板查看器與7預先安裝調色板;
          • 顏色歷史最近挑選的顏色;
          • 顯示標簽名稱,類別,編號,大小等元素信息;
          • 光標下的輪廓元素;
          • 自動將生成或采樣的顏色復制到CSS RGB,Hex和其他格式的剪貼板;
          • 使用鍵盤快速采樣頁面顏色的鍵盤快捷鍵。

          字體

          27. WhatFont

          當我們想查看網頁中文字的字體時,最常用的方法就是在控制臺查看文字的字體樣式。那還有沒有更簡單的方法呢?WhatFont 就是一個查看網頁字體的Chrome擴展。只需要的點擊擴展圖標,再點需要查看為文字即可:

          28. Fonts Ninja

          Fonts Ninja 可以從任何網站識別字體、添加書簽、試用并購買它們。

          標簽頁

          29. BrowserStack

          使用 BrowserStack 快速啟動擴展在任何瀏覽器中啟動一個新的測試會話。最多可設置 12 個瀏覽器以實現快速訪問并最大限度地減少切換瀏覽器所花費的時間。

          30. Toby

          Toby 是一款 Chrome 新標簽頁工具,能夠將未讀的標簽頁分組顯示在新標簽頁中,這樣就能把所有未看完的標簽頁都關閉了。分組相當于多個 Chrome 窗口,將你的標簽頁都拖進 Toby 中,就不需要實時開著占地方了。

          31. daily.dev

          該擴展提供了每日熱門開發者新聞,不需要再浪費時間搜索高質量的文章了。

          32. Momentum

          Momentum 擁有漂亮的新標簽頁面,每日更新精彩背景壁紙圖片,可設置每日新鮮事焦點以及跟蹤待辦事項,無廣告,無彈窗。

          33. The Great Suspender

          The Great Suspender 是一個輕量級的擴展用來減少 Chrome 的內存占用。如果同時打開許多選項卡,在可配置的時間之后未查看的選項卡將在后臺自動掛起,從而釋放該選項卡消耗的內存和 CPU。

          34. Session Buddy

          Session Buddy是一個可以幫助用戶查看、新增、編輯當前網站Session狀態的Chrome插件。用戶可以利用該插件保存網站當前的狀態以便在關閉Chrome或關閉計算機后恢復,從而達到節省內存的作用。

          Github

          35. Octotree

          Octotree 旨在讓 GitHub 體驗更好。通常,為了檢查 Github 中的子文件夾,需要手動單擊文件夾并導航。Octotree 擴展解決了這個問題。此擴展在項目的左側顯示存儲庫的目錄結構,這有助于更好地理解文件夾結構。

          1_EKF88oqIyX6FzgueCKdtXg.gif

          36. File Icons for GitHub and GitLab

          File Icons for GitHub and GitLab 可以將 GitHub 和 GitLab 上的原始文件圖標替換為特定文件類型的圖標。

          網頁測試

          37. axe DevTools

          ax DevTools 是一個快速、輕量級但功能強大的測試工具,由 Deque 開發的世界上最值得信賴的可訪問性測試引擎 axe-core 驅動。使用 ax DevTools 在網站開發過程中查找并修復更多可訪問性問題。

          38. OctoLinker

          OctoLinker 可以將特定語言的語句(如 include、require 或 import)轉換為鏈接。當打開一個包含多個導入語句的文件并且想要快速打開它時,只需將鼠標懸停在鏈接的文件上并單擊即可打開。

          39. Web Developer Checklist

          此擴展可幫助 Web 開發人員分析網頁是否違反最佳實踐。

          40. Check My Links

          Check My Links 是一個鏈接檢查器,它可以抓取網頁并查找損壞的鏈接。

          41. Checkbot

          Checkbot 是用于驗證一組HTML頁面上的鏈接的工具。Checkbot可以檢查一個或多個服務器上的單個文檔或一組文檔。它會創建一個報告,該報告匯總了引起某種警告或錯誤的所有鏈接。

          42. PageSpeed Insights

          Google Page Speed Insighs 是一款旨在優化所有設備上的網頁、提高網頁加載速度的工具。

          43. Meta SEO Inspector

          META SEO inspector是一款可以幫助用戶分析網頁的meta信息并得到SEO評估的谷歌瀏覽器插件。

          隱私廣告

          44. Ghostery

          Ghostery 是強大的隱私保護擴展程序。其主要有以下功能:

          • 攔截廣告:Ghostery 內置的廣告攔截工具可以移除網頁上的廣告,防止網頁雜亂無章,讓你專注于想看的內容。
          • 保護隱私:利用 Ghostery 可以查看和攔截所瀏覽的網站上的跟蹤器,控制收集數據的跟蹤器。增強反跟蹤功能還能將數據匿名化,進一步保護隱私。
          • 提高瀏覽速度:Ghostery 的智能攔截功能可以自動攔截和取消攔截跟蹤器來滿足網頁質量標準,提高網頁加載速度,優化網頁性能。

          45. AdBlock

          AdBlock 用來在YouTube、Facebook、Twitch和其他你喜愛的網站上攔截廣告和彈窗。

          效率工具

          46. Marinara

          番茄工作法(Pomodoro?)時間管理助理。? 長短兩種休息時間 ? 帶有倒計時顯示的工具欄圖標 ? 追蹤Pomodoro歷史和統計訊息 ? 可配置的長休間隔 ? 可配置的定時器時長 ? 桌面與新標簽頁通知 ? 超過20種音效可選的聲音通知 ? 計時器秒針走動音效

          47. Loom

          Loom 可以用來快速錄制視頻,并且能夠將錄制的視頻上傳到指定的網頁中,Loom還支持在用戶點擊啟動插件時,立即捕捉屏幕圖像,同時開始視頻錄制操作,還可以將錄制好的視頻復制到粘貼板中存儲。

          48. GoFullPage

          GoFullPage 是一款全屏截圖插件(整個網頁截圖),完整捕獲您當前頁面的屏幕,進行滾動截圖,而無需任何額外的權限。單擊擴展程序圖標,然后將其傳輸到屏幕快照的新標簽頁中,可以在其中將其下載為圖像或PDF,甚至只需拖動即可,保存到桌面。

          49. BetterViewer

          BetterViewer 可以提供更好的圖像查看體驗,旨在替代基于 Chrome 瀏覽器中內置的圖像查看模式。使用時,只需在頁面右鍵點擊圖片,選擇“在新標簽頁中打開圖片”即可。

          50. svg-grabber

          svg-grabber 是一個快速預覽并從網站獲取所有 svg 的工具。可以用來預覽、下載和復制網站中所有 SVG 圖標和插圖的代碼。


          .em字體設置

          body {font-size:100%;}
          h1 {font-size:3.75em;}
          h2 {font-size:2.5em;}
          p {font-size:0.875em;}
          復制代碼

          2.背景圖標居右

          .aa{
              background-image: url(arrow.png)no-repeat right center;
              background-image:url(nav-bar.jpg);
              background-repeat:no-repeat;
              background-position:right center;
          }
          復制代碼

          3.文本框超出部分顯示省略號:

          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;    
          復制代碼


          我自己是一名從事了多年開發的web前端老程序員,目前辭職在做自己的web前端私人定制課程,今年我花了一個月整理了一份最適合2020年學習的web前端學習干貨,各種框架都有整理,送給每一位前端小伙伴,想要獲取的可以關注我的頭條號并在后臺私信我:前端,即可免費獲取。

          一蒙版出現禁止頁面滾動

          1 window.onscroll=function(){
              document.body.scrollTop = 0
          };
          
          2 $('html,body').animate({scrollTop:'0'},100);
          $(".tan").bind('touchmove',function(e){  //禁止彈出框出來時進行滑動 
              e.preventDefault();
          });
          3 document.body.style.overflow='hidden';
          若鍵盤點擊的話,就要加上:
          var move=function(e){
              e.preventDefault && e.preventDefault();
              e.returnValue=false;
              e.stopPropagation && e.stopPropagation();
              return false;
          }
          var keyFunc=function(e){
              if(37<=e.keyCode && e.keyCode<=40){
                  return move(e);
              }
          }
          document.body.onkeydown=keyFunc;
          
          復制代碼

          二、按鈕點擊事件

          var button=$(':button');
          button.on('click',function(){
              button.css('background-color','white');
              $(this).css('background-color','#FB3336');
          })
          復制代碼

          三、安卓手機里,h5頁面沒有充滿body導致左右滑動的問題

          首先聲明一下:

          <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
          然后
          html,body {width:100%;height:100%;overflow-x:hidden;}
          
          復制代碼

          四、關于頁面左右滾動的問題

          1.<body scoll=no> 全禁止
          2.<body style="overflow:scroll;overflow-y:hidden"> 禁止縱向滾動條
          3.<body style="overflow:scroll;overflow-x:hidden"> 禁止縱向滾動條
          4.overflow屬性: 檢索或設置當對象的內容超過其指定高度及寬度時如何顯示內容
          5.overflow: auto; 在需要時內容會自動添加滾動條
          6.overflow: scroll; 總是顯示滾動條
          7.overflow-x: hidden; 禁止橫向的滾動條
          8.overflow-y: scroll; 總是顯示縱向滾動條
          復制代碼

          五、 content && header之間的亮條怎么消除

          .mui-bar-nav{
              -webkit-box-shadow: none;
              box-shadow: none;
          }
          復制代碼

          六、刪除選項

          $(".shanchu").click(function(){
              $(this).parent().remove()
          })
          復制代碼

          七、表單提交按鈕時,鼠標放在上面顯示小手的方法:

          需要對元素屬性的css的cursor進行設置
          1、default    默認光標(通常是一個箭頭)
          2、auto   默認。瀏覽器設置的光標。 
          3、crosshair   光標呈現為十字線。    
          4、pointer    光標呈現為指示鏈接的指針(一只手)    
          5、move    此光標指示某對象可被移動。    
          6、e-resize    此光標指示矩形框的邊緣可被向右(東)移動。    
          7、ne-resize    此光標指示矩形框的邊緣可被向上及向右移動(北/東)。    
          8、nw-resize    此光標指示矩形框的邊緣可被向上及向左移動(北/西)。    
          9、n-resize    此光標指示矩形框的邊緣可被向上(北)移動。    
          10、se-resize    此光標指示矩形框的邊緣可被向下及向右移動(南/東)。    
          11、sw-resize    此光標指示矩形框的邊緣可被向下及向左移動(南/西)。  
          12、s-resize    此光標指示矩形框的邊緣可被向下移動(南)。    
          13、w-resize    此光標指示矩形框的邊緣可被向左移動(西)。    
          14、text    此光標指示文本。    
          15、wait    此光標指示程序正忙(通常是一只表或沙漏)。    
          16、help    此光標指示可用的幫助(通常是一個問號或一個氣球)。    
          要實現鼠標移上去顯示手形、需要在你的提交按鈕上增加css cursor屬性,并將它的值設置為pointer;
          如下:<input type="submit" name="submit" value="發布留言" class="subimt" onclick="display_alert()" style="cursor:pointer" />
          復制代碼

          八、怎么清除table里面tbody的內容

          $("#test tbody").html("");
          復制代碼

          九、動態獲取表格的行數

          var bv=$("#tabd tr").length-1;
          $("#sp4").html(bv);     //動態的獲取注數
          復制代碼

          十、多個按鈕點擊變色,再點擊還原

          $(".jixuan  input[type=button]").toggle(function(){
              $(this).css("background-color","yellow");
              $(this).css("cursor","pointer")
              },function(){
              $(this).css("background-color","white");
              $(this).css("cursor","pointer");
          }) 
          復制代碼

          十一、單選按鈕顧名思義用于單選的場合,例如,性別,職業的選擇等,語法如下:

          <input type="radio" name="gender" value="男" checked />
          常用屬性迅美科技整理如下:
          1.type="radio"
          type屬性設置為radio,表示產生單一選擇的按鈕,讓用戶單擊選擇;
          2.name="gender"
          radio組件的名稱,name屬性值相同的radio組件會視為同一組radio組件,而同一組內只能有一個radio組件被選擇;
          3.value="男"
          radio組件的值,當表單被提交時,已選擇的radio組件的value值,就會被發送進行下一步處理, radio組件的value屬性設置的值 
          無法從外觀上看出,所以必須在radio組件旁邊添加文字,此處的文字只是讓用戶了解此組件的意思.
          4.checked
          設置radio組件為已選擇,同一組radio組件的name性情值必須要相同
          復制代碼

          十二、網頁中,公共頭部和側邊欄的引用

          1、<?php include("header.html");?>
          2、使用ssi技術頁面生成shtml文件,只用在頭部文件位置加入<!--#include file="header.htm" -->,
          然后修改的時候只要修改header.htm文件就可以了。使用shtml的好處是對搜索引擎比較友好,需要處理的文件在服務器端完成的,
          不會加重訪問者的瀏覽器負擔。
          復制代碼

          十三、錨點鏈接上下定位偏移解決

          1、JS解決的方法

          if (window.location.hash.indexOf('#') >= 0) {
              $('html,body').animate({
              scrollTop: ($(window.location.hash).offset().top - 50) + "px"
              },
              300);
          }; //主要修復評論定位不準確BUG
          $('#comments a[href^=#][href!=#]').click(function() {
              var target = document.getElementById(this.hash.slice(1));
              if (!target) return;
              var targetOffset = $(target).offset().top - 50;
              $('html,body').animate({
                  scrollTop: targetOffset
              },
              300);
              return false;
          }); //主要修復評論定位不準確BUG
          復制代碼

          2、解決辦法

          能用css自然不想用js解決,因為在加載方面,css總是先加載,并且速度很快。
          
          typecho的評論HTML結構是這樣的:
          
          <li id="comment-277" class="comment-body comment-child comment-level-odd comment-even comment-by-author">
          我們給comment-body加上css
          
          .comment-body {
              position: relative;
              padding-top: 50px;
              margin-top: -50px;
          }
          /*修復評論跳轉定位問題*/
          完美兼容chrome和Firefox,其他瀏覽器未測試。
          復制代碼

          十四、蒙版彈出禁止蒙版后面的內容滾動

          .ovfHiden{overflow: hidden;height: 100%;}
          $('.bzh .l1 a').click(function(){
              $(".baok").show();
              $(".baod").show();
              $('html,body').addClass('ovfHiden');
          });
          $('.baod .img1').click(function(){
          $('html,body').removeClass('ovfHiden');
              $(".baok").hide();
              $(".baod").hide();
          });
          復制代碼

          十五、獲取復選框點擊的次數

          $("#compute").click(function(){
              $('input').live('click',function(){ 
              //alert($('input:checked').length); 
              $("#show").html($('input:checked').length);
              });
          });
          復制代碼

          十六、Tab選項卡切換

          1.js

          $('footer ul li').click(function(){
              var index = $(this).index();
              $(this).attr('class',"content").siblings('ul li').attr('class','ss');
              $('.content').eq(index).show(200).siblings('.content').hide();
              });
          
          $('.ka ul li').click(function(){
              var index = $(this).index();
              $(this).attr('class',"zi").siblings('ul li').attr('class','ll');
              $(this).parent().next().find(".zi").hide(). eq(index).show();
          });
          復制代碼

          2.html

          <div class="carindex-cnt">
                  <ul class="nav">
                      <li>續保方案</li>
                      <li>熱銷方案</li>
                      <li>自定義方案</li>
                  </ul>
                  <div class="tabcontent">
                      <div class="zi">
                          <p class="altp">此方案為您上一年的投保記錄</p>
                          <ul class="xiur">
                              <li>
                                  <label for="saveType2">交強險</label>
                                  <div  class="right-cnt">
                                      <input type="text" class="coverage" disabled="disabled" value="不投保"/>
                                      <ul class="datas" style="display: none;">
                                          <li ref="1">投保</li>
                                          <li ref="2">不投保</li>
                                      </ul>
                                  </div>
                              </li>
                              <li>
                                  <label for="saveType2">商業險</label>
                                  <div  class="right-cnt">
                                      <input type="text" class="coverage" disabled="disabled" value="不投保"/>
                                      <ul class="datas" style="display: none;">
                                          <li ref="1">投保</li>
                                          <li ref="2">不投保</li>
                                      </ul>
                                  </div>
                              </li>
                          </ul>
                          <p class="title">商業主險</p>
                          <ul class="xiur">
                              <li>
                                  <span>車輛損失險</span>
                                  <label for="abatement0" class="labels">
                                      <input class="mui-checkbox checkbox-green" type="checkbox" name="abatement" >
                                  </label>
                                  <div  class="right-cnt">
                                      <input type="text" class="coverage" disabled="disabled" value="不投保"/>
                                      <ul class="datas" style="display: none;">
                                          <li ref="1">投保</li>
                                          <li ref="2">不投保</li>
                                      </ul>
                                  </div>
                              </li>
                            
                          </ul>
                      </div>
                      <div class="zi" style="display: none">
                          <ul class="xiur">
                              <li>
                                  <label for="saveType2">交強險</label>
                                  <div  class="right-cnt">
                                      <input type="text" class="coverage" disabled="disabled" value="不投保"/>
                                      <ul class="datas" style="display: none;">
                                          <li ref="1">投保</li>
                                          <li ref="2">不投保</li>
                                      </ul>
                                  </div>
                              </li>
                              <li>
                                  <label for="saveType2">商業險</label>
                                  <div  class="right-cnt">
                                      <input type="text" class="coverage" disabled="disabled" value="不投保"/>
                                      <ul class="datas" style="display: none;">
                                          <li ref="1">投保</li>
                                          <li ref="2">不投保</li>
                                      </ul>
                                  </div>
                              </li>
                          </ul>
                      </div>
                  </div>
          </div>  
          復制代碼

          3.js

          $('.nav li').click(function () {
              var index = $(this).index();
              $(this).parent().next().find(".zi").hide().eq(index).show();
          })
          
          復制代碼

          十七、form表為空時,提交按鈕禁用

          $(function(){            
              $('.main button').click(function(){
                  if(($('.ip1').val() !="") && ($('.ip2').val() !="")){
                      $('.main button').css('background','#ff8100');
                      $('.main button').attr('disabled', true);
                      }else{
                      $('.main button').css('background','#D0D0D0');
                      $('.main button').attr('disabled', false);
                  }
              })
          })
          復制代碼

          十八、上拉事件和下拉事件

          $(window).scroll(function(){
              var scrollTop = $(this).scrollTop();               //滾動條距離頂部的高度
              var scrollHeight =$(document).height();                   //當前頁面的總高度
              var windowHeight = $(this).height();                   //當前可視的頁面高度
              if(scrollTop + windowHeight >= scrollHeight){    //距離頂部+當前高度 >=文檔總高度 即代表滑動到底部
                  alert("上拉加載,要在這調用啥方法?");
              }else if(scrollTop<=0){         //滾動條距離頂部的高度小于等于0
                  alert("下拉刷新,要在這調用啥方法?");
              }
          });                                                          ——>移動端
          
          $(function(){    
              $(window).scroll(function() {  
                  var scrollTop = $(this).scrollTop(),scrollHeight = $(document).height(),windowHeight = $(this).height();  
                  var positionValue = (scrollTop + windowHeight) - scrollHeight;  
                  if (positionValue == 0) {  
                      //do something  
                  }  
              });  
          });  
          復制代碼

          十九、左滑和右滑事件

          var obj;
          var startx;
          var starty;
          var overx;
          var overy;
              for(var i=1;i<=$("li").length;i++){          //為每個li標簽添加事件
              obj = document.getElementById(i);       //獲取this元素
              evenlistener(obj);      //調用evenlistener函數并將dom元素傳入,為該元素綁定事件
          }
          
          function evenlistener(obj){
              obj.addEventListener('touchstart', function(event) {        //touchstart事件,當鼠標點擊屏幕時觸發
              startx = event.touches[0].clientX;              //獲取當前點擊位置x坐標
              starty = event.touches[0].clientY;              //獲取當前點擊位置y坐標
              $(".sdf").text("x:"+startx+",y:"+starty+"")     //賦值到頁面顯示
              } , false);         //false參數,設置事件處理機制的優先順序,具體不多說,true優先false
              obj.addEventListener('touchmove', function(event) {         //touchmove事件,當鼠標在屏幕移動時觸發
              overx = event.touches[0].clientX;           //獲取當前點擊位置x坐標
              overy = event.touches[0].clientY;           //獲取當前點擊位置y坐標
              var $this = $(this);            //將dom對象轉化為jq對象,由于項目用到jquery,直接使用其animate方法
          
              if(startx-overx>10){         //左滑動判斷,當左滑動的距離大于開始的距離10進入
              $($this).animate({marginLeft:"-55px"},150);         //實現左滑動效果
              }else if(overx-startx>10){       //右滑動判斷,當右滑動的距離大于開始的距離10進入
              $($this).animate({marginLeft:"0px"},150);           //恢復
              }
          } , false);
              obj.addEventListener('touchend', function(event) {          //touchend事件,當鼠標離開屏幕時觸發,項目中無用到,舉例
              $(".sf").text("x:"+overx+",y:"+overy+"")
              } , false);
          }
          復制代碼

          二十、各大瀏覽器的判斷

          var Sys = {};
          var ua = navigator.userAgent.toLowerCase();
          var s;
          (s = ua.match(/rv:([\d.]+)\) like gecko/)) ? Sys.ie = s[1] :
          (s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] :
          (s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] :
          (s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] :
          (s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] :
          (s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0;
          if (Sys.ie){
              $("*").css({fontFamily:"微軟雅黑"});
          };
          if (window.ActiveXObject){
          Sys.ie = ua.match(/msie ([\d.]+)/)[1];
          if (Sys.ie<=9){
              alert('你目前的IE版本為'+Sys.ie+'版本太低,請升級!');
              location.href="http://windows.microsoft.com/zh-CN/internet-explorer/downloads/ie";
              }
          }
          var UA=navigator.userAgent;
          if(is360se = UA.toLowerCase().indexOf('360se')>-1 ){
          
          }else{
              $("*").css({fontFamily:"微軟雅黑"});
          }
          
          360瀏覽器基于IE內核的,360急速瀏覽器內核基于谷歌的
          復制代碼

          二十一、form表單中點擊button按鈕刷新問題

          button,input type=button按鈕在IE和w3c,firefox瀏覽器區別: 
          1、當在IE瀏覽器下面時,button標簽按鈕,input標簽type屬性為button的按鈕是一樣的功能,不會對表單進行任何操作。 
          2、但是在W3C瀏覽器,如Firefox下就需要注意了,button標簽按鈕會提交表單,而input標簽type屬性為button不會對表單進行任何操作。
          為button按鈕增加一個type=”button”屬性。
          復制代碼

          二十二、textrare文字輸入提示:

          <textarea name="" id="sign" maxlength=30 onKeyUp="keypress1()"></textarea>
          <div class="tish">
          <span id="number">0</span><span>/30</span>
          </div>
          
          function keypress1() //text輸入長度處理 
          { 
              var text1=document.getElementById("sign").value; 
              var len=text1.length; 
              var show=len; 
              document.getElementById("number").innerText=show; 
          } 
          復制代碼

          二十三、iframe操作

          1:父頁面操作iframe子頁面

          $('#ifrme').load(function(){
          $('#ifrme').contents().find('.baod .img1').click(function(){
              $(.ifrme').contents().find('.baod').hide();
              $('.baok',window.parent.document).hide();
              $('html,body',window.parent.document).removeClass('ovfHiden');
              });
          })
          * .ifrme父頁面的ID為iframe的父級
              .baod .img1是iframe頁面里的元素
          復制代碼

          2:子頁面操作父頁面

          $('.baod .bt1').click(function(){
              $('.baod').hide();
              $('.edit',window.parent.document).hide();
              $(".baok", window.parent.document).hide(); 
              $('html,body',window.parent.document).removeClass('ovfHiden');
          });
          *.baod .bt1子頁面里的元素
          window.parent.document父級窗口
          .edit父級頁面元素
          復制代碼

          二十四、toggle開關切換圖標或是元素的隱藏

          $('.other .pg').click(function(){
              $(this).toggleClass ("pots");
              $('.below').slideToggle(300);
          })
          
          * .other .pg元素名稱
          pots 點擊元素要切換的圖標(以background()形式的圖標)
          .below要進行toggle的內容
          復制代碼

          二十五、彈框居中

          $(".btnDel").click(function() {  
          //$(".box-mask").css({"display":"block"});  
              $(".box-mask").fadeIn(500);  
              center($(".box"));  
              //載入彈出窗口上的按鈕事件  
              checkEvent($(this).parent(),            $(".btnSure"), $(".btnCancel"));  
          });  *center  彈框名稱
          
          function center(obj) {  
              //obj這個參數是彈出框的整個對象  
              var screenWidth = $(window).width(), screenHeigth = $(window).height();  
              //獲取屏幕寬高  
              var scollTop = $(document).scrollTop();  
              //當前窗口距離頁面頂部的距離  
              var objLeft = (screenWidth - obj.width()) / 2;  
              ///彈出框距離左側距離  
              var objTop = (screenHeigth - obj.height()) / 2 + scollTop;  
              ///彈出框距離頂部的距離  
              obj.css({  
                  left:objLeft + "px",  
                  top:objTop + "px"  
              });  
              obj.fadeIn(500);  
              //彈出框淡入  
              isOpen = 1;  
              //彈出框打開后這個變量置1 說明彈出框是打開裝填  
              //當窗口大小發生改變時  
              $(window).resize(function() {  
                  //只有isOpen狀態下才執行  
                  if (isOpen == 1) {  
                      //重新獲取數據  
                      screenWidth = $(window).width();  
                      screenHeigth = $(window).height();  
                      var scollTop = $(document).scrollTop();  
                      objLeft = (screenWidth - obj.width()) / 2;  
                      var objTop = (screenHeigth - obj.height()) / 2 + scollTop;  
                      obj.css({  
                          left:objLeft + "px",  
                          top:objTop + "px"  
                      });  
                      obj.fadeIn(500);  
                  }  
          });  
              //當滾動條發生改變的時候  
          $(window).scroll(function() {  
              if (isOpen == 1) {  
                  //重新獲取數據  
                  screenWidth = $(window).width();  
                  screenHeigth = $(window).height();  
                  var scollTop = $(document).scrollTop();  
                  objLeft = (screenWidth - obj.width()) / 2;  
                  var objTop = (screenHeigth - obj.height()) / 2 + scollTop;  
                  obj.css({  
                      left:objLeft + "px",  
                      top:objTop + "px"  
                  });  
                  obj.fadeIn(500);  
              }  
          });  
          復制代碼

          二十六、css和js進行奇偶選擇器

          css

          :nth-child(odd){background-color:#FFE4C4;}奇數行
          :nth-child(even){background-color:#F0F0F0;}偶數行
          復制代碼

          js

          $("table  tr:nth-child(even)").css("background-color","#FFE4C4");    //設置偶數行的背景色
          $("table  tr:nth-child(odd)").css("background-color","#F0F0F0");    //設置奇數行的背景色
          復制代碼

          二十七、jQuery中live()使用報錯,TypeError: $(...).live is not a function

          jquery中的live()方法在jquery1.9及以上的版本中已被廢棄了,如果使用,會拋出TypeError: $(...).live is not a function錯誤。
          
          解決方法:
          
          之前的用法:
          
          .live(events, function)  
          
          新方法:
          
          .on(eventType, selector, function)
          
          若selector不需要,可傳入null
          
          
          例子1:
          
          之前:
          
          $('#mainmenu a').live('click', function)
          
          之后:
          
          $('#mainmenu').on('click', 'a', function)
          
          
          例子2:
          
          之前:
          
          $('.myButton').live('click', function)
          
          之后(應使用距離myButton最近的節點):
          
          $('#parentElement').on('click', ‘.myButton’, function)
          
          若不知最近的節點,可使用如下的方法:
          
          $('body').on('click', ‘.myButton’, function)
          復制代碼

          二十八、iframe滾動條問題

          iframe嵌入的滾動條可以用iframe里面頁面的大小覆蓋掉iframe的滾動條
          復制代碼

          二十九、點擊圖片下載(不用新窗口打開)

          <a class="downs"  style="display:'+display+'" onclick="downimg(\''+list[i].skuTieTu+'\')">下載</a>
          復制代碼

          js方法

          /**
          * 圖片單獨下載
          */
          function downimg(skuTieTu){
              console.log(skuTieTu)
              let src = skuTieTu;
              var canvas = document.createElement('canvas');
              var img = document.createElement('img');
              img.onload = function(e) {
              canvas.width = img.width;
              canvas.height = img.height;
              var context = canvas.getContext('2d');
              context.drawImage(img, 0, 0, img.width, img.height);
              canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
              canvas.toBlob((blob)=>{
                  let link = document.createElement('a');
                  link.href = window.URL.createObjectURL(blob);
                  link.download = 'zzsp'; 
                  link.click();  
              }, "image/jpeg");
          }
          img.setAttribute("crossOrigin",'Anonymous');
          img.src = src;
          復制代碼

          三十、ajax里面條件判斷

          $.ajax({
              type: "post",
              data: 
              contentType:
              url: 
              beforeSend: function () {
                  if(){
                  
                  }else{
                  
                  };
              },
              success: function (data) {
                  alert("保存失敗");
              },
              error: function (data) {
                  alert("保存成功");
              }
          });
          復制代碼

          三十一、ajax里面在數據請求之前加layui.load()時,請求狀態必須是異步的才行( async: true)

          $.ajax({
              type:"post",
              url: API,
              data: {
                  'a':'project.kujiale.plan.YongliaoUser'
              },
              dataType: "json",
              async: true,
              beforeSend: function () {
                  layer.load(1);
              },
              success: function(data) {   
                  var item =data.data;
                  list = item
                  if(data.code==0){
                      layer.closeAll();
                      var url = '/module/designplan/searchplan/searchlist.jsp';
                      layer.open({
                      type: 2,
                      title: "搜索方案",
                      shadeClose: true,
                      shade: 0.8,
                      area: ['700px','500px'],
                      content: [url]
                      });
                  }else{
                      layer.msg(data.msg);
                  }
              }
          });
          
          復制代碼

          三十二、js根據元素的屬性獲取到改元素其他屬性的值

          jquery
          $("a[id=search]").attr("data-search")
          
          原生js
          document.querySelector("a[id=search]").getAttribute("data-search") //根據當前元素的屬性獲取該元素其他屬性的值
          
          document.querySelector("a[id=search]").text //根據當前屬性獲取該元素的值
          document.querySelector("a[id=search]").innerText //根據當前屬性獲取該元素的值    
          復制代碼

          三十三、數組對象提交時轉化問題

          JSON.stringify(userList)
          復制代碼

          三十四、layui使用

          1、關閉彈窗

          layer.msg('分配成功',{time: 1000},function () {
              var index = parent.layer.getFrameIndex(window.name);
              parent.layer.close(index);
          })
          復制代碼

          2、關閉彈窗,刷新頁面

          window.location.reload();//刷新當前頁面
          window.parent.location.reload();//刷新父級頁面
          復制代碼

          三十五、js創建下載方式

          download(data.data);
          
          function downpdf(data){
              var link = document.createElement('a');
              link.href = data;
              link.target = '_blank';
              link.click();
              delete link;
          }
          復制代碼

          三十六、高階函數

          const isYoung = age => age < 25;
          
          const message = msg => "He is "+ msg;
          
          function isPersonOld(age, isYoung, message) {
              const returnMessage = isYoung(age)?message("young"):message("old");
              return returnMessage;
          }
          
          // passing functions as an arguments
              console.log(isPersonOld(13,isYoung,message))
          // He is young
          復制代碼

          遞歸

          遞歸是一種函數在滿足一定條件之前調用自身的技術。只要可能,最好使用遞歸而不是循環。你必須注意這一點,瀏覽器不能處理太多遞歸和拋出錯誤。
          下面是一個演示遞歸的例子,在這個遞歸中,打印一個類似于樓梯的名稱。我們也可以使用for循環,但只要可能,我們更喜歡遞歸。
          復制代碼
          function printMyName(name, count) {
              if(count <= name.length) {
                  console.log(name.substring(0,count));
                  printMyName(name, ++count);
              }
          }
          
          console.log(printMyName("Bhargav", 1));
          
          /*
              B
              Bh
              Bha
              Bhar
              Bharg
              Bharga
              Bhargav
          */
          
          // withotu recursion
          var name = "Bhargav"
          var output = "";
          for(let i=0; i<name.length; i++) {
              output = output + name[i];
              console.log(output);
          }


          作者:山水有輕音
          鏈接:https://juejin.im/post/6873003814065012750


          主站蜘蛛池模板: 日韩一区在线视频| 日韩在线一区二区三区免费视频| 精品国产一区二区三区久久蜜臀| 亚洲av无码一区二区三区天堂古代 | 91精品一区二区综合在线| 精品一区二区三区高清免费观看| 日韩精品一区二区三区在线观看l 日韩精品一区二区三区毛片 | 久久久久人妻精品一区蜜桃| 最美女人体内射精一区二区| 中文字幕在线观看一区二区三区| 岛国精品一区免费视频在线观看| 日韩精品无码人妻一区二区三区| 一区国严二区亚洲三区| 国产精品女同一区二区久久 | 91一区二区三区四区五区| 亚洲一区二区电影| 国产午夜精品片一区二区三区| 国产一区二区三区影院| 国产精品无码一区二区在线观| 日本精品视频一区二区| 国产vr一区二区在线观看| 国产乱码伦精品一区二区三区麻豆| 波多野结衣AV无码久久一区| 国产精品毛片一区二区三区| 亚洲国产高清在线精品一区| 欧美日本精品一区二区三区| 日韩福利视频一区| 国产在线观看一区精品| 久久久91精品国产一区二区| 亚洲一区二区三区成人网站| 国产成人无码aa精品一区| 99精品一区二区三区| 亚洲色偷精品一区二区三区| 国产福利微拍精品一区二区 | 福利一区二区在线| 中文字幕av无码一区二区三区电影 | 精品人无码一区二区三区| 国产精品久久久久一区二区三区| 日本一区二区高清不卡| 国产一区二区三区免费| 亚洲AV日韩精品一区二区三区|