一個使用 Web Components 的音樂播放器: MelodyPlayer

来源:https://www.cnblogs.com/rocket1184/archive/2018/04/27/announcing-melody-player.html
-Advertisement-
Play Games

先上效果預覽: Web Components 首先,什麼是 Web Components ? "MDN" 給出的定義是: Web Components 是一套不同的技術,允許您創建可重用的定製元素(它們的功能封裝在您的代碼之外)並且在您的web應用中使用它們。 ... ... 實現web compo ...


先上效果預覽:





Web Components

首先,什麼是 Web Components ?

MDN 給出的定義是:

Web Components 是一套不同的技術,允許您創建可重用的定製元素(它們的功能封裝在您的代碼之外)並且在您的web應用中使用它們。
... ...
實現web component的基本方法通常如下所示:

  1. 使用 ECMAScript 2015 類語法創建一個類,來指定web組件的功能(參閱類獲取更多信息)。
  2. 使用 CustomElementRegistry.define() 方法註冊您的新自定義元素 ,並向其傳遞要定義的元素名稱、指定元素功能的類以及可選的,其所繼承自的元素。
  3. 如果需要的話,使用 Element.attachShadow() 方法將一個 Shadow DOM 附加到自定義元素上。使用通常的 DOM 方法向 Shadow DOM 中添加子元素、事件監聽器等等。
  4. 如果需要的話,使用 <template><slot> 方法定義一個 HTML 模板。再次使用常規 DOM 方法克隆模板並將其附加到您的 Shadow DOM 中。
  5. 在頁面任何您喜歡的位置使用自定義元素,就像使用常規 HTML 元素那樣。

說人話,就是先定義一個類

class MyCompo extends HTMLElement {
    constructor() {
        super();  // 一定要先調用 super
        // 為所欲為
    }
}

在裡面實現需要的功能,比如給自己添加子元素和事件監聽器,設置樣式等,就像在寫平常的 JS 代碼一樣。

然後,註冊這個元素:

window.customElements.define('my-compo', MyCompo)

根據 CustomElements v1 標準,自定義元素的名稱必須包含一個橫線。

最後,在 HTML 裡面寫入這個標簽:

<my-compo></my-compo>

標簽必須有結束標簽與之對應,不能使用自閉合標簽。

然後就可以充分享受 CustomElements 帶來的樂趣了,是不是很簡單呢 (誤

通常,Custom Elements 會與 ShadowDOM 結合使用。那什麼是 ShadowDOM 呢?

ShadowDOM

MDN 給出的定義是:

An important aspect of web components is encapsulation — being able to keep the markup structure, style, and behavior hidden and separate from other code on the page so that different parts do not clash, and the code can be kept nice and clean. The Shadow DOM API is a key part of this, providing a way to attach a hidden separate DOM to an element.

大概翻譯一下:

封裝是 Web Components 中重要的一環,可以將元素的 DOM 樹結構、樣式以及行為邏輯與頁面中的其他部分相隔離以避免衝突,並使你的代碼保持整潔。 Shadow DOM API 是其中的關鍵部分,它提供了向元素中插入隱藏 DOM 子樹的方法。

簡言之,Shadow DOM API 可以在任意元素內部插入一個隔離的 DOM 子樹,其中的元素與樣式與外部 DOM 保持隔離,不會影響到外部。所以無需擔心 CSS 代碼相互衝突。

說了這麼多,相容性怎麼樣呢?

抱歉,打擾了(

但我們可以使用 Polyfill ,比如這個 webcomponentsjs ,這裡就不展開介紹了。

我的博客園頁面中已經加入了註入 Polyfill 的代碼,如果你的瀏覽器不能正確載入,那真的改換瀏覽器了 ...

<script>
(function () {
    const sd = 'attachShadow' in Element.prototype;
    const ce = 'customElements' in window;
    if (!sd && !ce) {
        document.write('<script src="https://files.cnblogs.com/files/rocket1184/webcomponents-sd-ce.js"><\/script>')
        return;
    }
    !ce && document.write('<script src="https://files.cnblogs.com/files/rocket1184/custom-elements.min.js"><\/script>')
    !sd && document.write('<script src="https://files.cnblogs.com/files/rocket1184/shadydom.min.js"><\/script>')
})();
</script>

MelodyPlayer

額,跑題了,今天發文章的目的其實是介紹播放器啊,播放器播放器~~~

首先,播放器支持兩種模式,一種是單曲模式,就像這樣:



預設播放一遍之後停止,也可以點擊右邊第二個按鈕切換到單曲迴圈模式。

然後是列表模式,就像文章一開始時展示的那樣,多了 上一曲 和 下一曲 的按鈕,預設播放列表一遍後停止。也可以選擇列表迴圈、單曲迴圈或是隨機模式。

最右邊的按鈕可以展開/收起歌詞面板。支持一或兩個歌詞同時顯示,還有流暢的滾動動畫。歌詞載入失敗後會有提示。

技術棧與優化

JS 部分使用了 ECMAScript 2015 各種語法,以及 JSX 。但並沒有使用 React ,而是用 babel 自定義 JSX @pragma ,並實現了一個自定義的 createElement 。 Webpack 配置可以參見 這裡

CSS 部分使用了 Less ,但並沒有生成獨立的樣式文件,也沒有用 style-loader 。在 Webpack 的配置中,僅使用 less-loader 將 *.less 轉譯為 *.css ,然後使用 css-loader 解析 CSS 中的 url() 部分,併在 JS 代碼中將解析後的 CSS 字元串添加到 ShadowRoot 下。

圖標使用了 Google 的 Material Design Icons ,但並沒有全量引入。我只將需要用到的 10 個圖標提取出來,生成了字體的子集,只有不到 1KB 大小。然後使用 url-loader 將字體轉為 Data URL 並內聯在 CSS 中。關於壓縮字體的方法及原理,請移步我的獨立博客:製作極限壓縮的 Material Icons 圖標字體

經過上述的優化,整個 melody-player.min.js 只有不到 23KB 的大小。


最後,附上 GitHub 鏈接,歡迎 Star ~

GitHub 倉庫: rocka/melody-player
GitHub Demo: MelodyPlayer Demo


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Zookeeper概念簡介: Zookeeper是為用戶的分散式應用程式提供協調服務的 zookeeper是為別的分散式程式服務的 Zookeeper本身就是一個分散式程式(只要有半數以上節點存活,zk就能正常服務) Zookeeper所提供的服務涵蓋:主從協調、伺服器節點動態上下線、統一配置管理、 ...
  • 根據以上的代碼生成的表,自動生成的簡單的添加、刪除、修改、查詢的存儲過程(關聯還沒有考慮,可以考慮進去) 自動生成實體(老版的)未考慮預設值 ...
  • 兩台ubuntu 雲伺服器,分別redis主從伺服器,ip地址是:123.207.96.138(主)139.199.167.251(從) 安裝redis,在這裡我建議給redis設置密碼,之前看過一篇文章,就是因為redis沒有設置密碼,導致redis伺服器被黑了。首先修改redis.conf配置文 ...
  • MongoDB 中的關係運算符,邏輯運算符,數組條件,內嵌文檔,正則過濾,正、倒序排序,限定數量 ...
  • 首先,需要打開手機的USB調試和微信的TBS 調試。然後,打開chrome://inspect,點擊Inspect。此時,如果沒有Fan牆或使用離線開發者工具包,會出現空白頁面: 解決方法: Fan牆或使用離線開發者工具包後,還是會出現左側空白,簡單修改css樣式激活一下就可以了,如下動圖演示: 微 ...
  • 一、項目介紹 【知識準備】 ①Android Interface definition language(aidl,android介面定義語言),其目的實現跨進程的調用。進程是程式在os中執行的載體,一個程式對應一個進程,不同進程就是指不同程式,aidl實現不同程式之間的調用。 ②主線程與子線程通信 ...
  • 做安卓開發時一定要註意,主線程不能更改UI界面,如果出現程式運行時崩潰的情況,如果沒有明顯的語法錯誤,請檢查自己的進程是否出現衝突,崩潰。如果有與後臺的連接,即請求向伺服器發送請求的時尤其需要註意,或出現沒有報錯,但就是網路請求這段代碼不會執行,這種情況下,如果設置的參數或者其他地方沒有什麼問題,但 ...
  • 前言: ​ 這是每天看github上面的一位大佬 "冴羽" [的博客 自己加以自己的理解總結的 是指程式源碼中定義變數的區域 作用域決定瞭如何查找變數,也就是度額定當前執行代碼對變數的訪問許可權 JavaScript 使用的是 (lexical scoping) 也就是靜態作用域 靜態作用域與動態作用 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...