国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

前端玩轉 Emoji 表情符號,看這一篇就夠了!

開發 前端
Emoji 是一種圖形符號,最初由日本電信運營商在 1990 年代引入,用于增強短信和網頁的表達能力。隨著時間的發展,Emoji 已經成為通信中不可或缺的一部分,廣泛應用于社交媒體、電子郵件、即時通訊工具等各種平臺。

Emoji 已經成為我們日常溝通中不可或缺的一部分,本文就來了解一下在前端中如何玩轉 Emoji!

Emoji 基本概念

前置知識

在學習 Emoji 之前,我們先來一些和 Emoji 相關的前置知識。

  • Unicode:

a.定義: 一個國際標準,旨在為世界上幾乎所有的字符(包括字母、數字、符號、標點符號和表情符號等)提供唯一的數字表示形式。它的主要目標是確保在不同的平臺、操作系統和設備之間能夠一致地表示和處理文本數據。

b.特點:

統一編碼:Unicode 為每種語言中的每個字符分配了一個唯一的編號(稱為碼點),從而解決了不同編碼系統之間的不兼容問題。

廣泛覆蓋:Unicode 包含了幾乎所有現代語言的字符,并且還在不斷擴展以支持更多的符號和歷史文字。

多種實現方式:Unicode 支持多種編碼格式,如 UTF-8、UTF-16 和 UTF-32,以便在不同的應用場景中靈活使用。

  • 碼點:
  • 定義: 指在 Unicode 標準中為每個字符分配的一個唯一的數字值。它通常用十六進制表示,并帶有前綴 U+ 來標識這是一個 Unicode 碼點。
  • 舉例:

a.字母 A 的 Unicode 碼點是 U+0041。

b.笑臉 Emoji ?? 的 Unicode 碼點是 U+1F60A。

  • 范圍: Unicode 定義了從 U+0000 到 U+10FFFF 的碼點范圍,總共可以表示超過一百萬個字符。這個范圍分為以下幾部分:
  • 基本多文種平面:從 U+0000 到 U+FFFF,包含最常見的字符。

  • 輔助平面:從 U+10000 到 U+10FFFF,用于表示較少見的字符和 Emoji。

  • 編碼方式: Unicode 有多種編碼方式,常見的有 UTF - 8、UTF - 16 和 UTF - 32。

  • UTF - 8:一種可變長度的編碼方式,使用 1 到 4 個字節來表示一個字符。它對 ASCII 字符采用單字節編碼,兼容 ASCII 標準,因此在互聯網上得到了廣泛應用。

  • UTF - 16:使用 2 個或 4 個字節來表示一個字符,常用于操作系統和編程語言中,如 Java 和 JavaScript 默認使用 UTF - 16 編碼。

  • UTF - 32:固定使用 4 個字節來表示一個字符,編碼簡單直接,但會占用較多的存儲空間。

Emoji 是什么?

Emoji 是一種圖形符號,最初由日本電信運營商在 1990 年代引入,用于增強短信和網頁的表達能力。隨著時間的發展,Emoji 已經成為通信中不可或缺的一部分,廣泛應用于社交媒體、電子郵件、即時通訊工具等各種平臺。

Emoji 本質上是 Unicode 字符集中的一部分,每個 Emoji 都有一個對應的唯一 Unicode 編碼。在最新的 Unicode 16.0 版本中,共指定了 3790 個 Emoji 及其編碼。

圖片圖片

Emoji 對應的 Unicode 編碼:https://unicode.org/emoji/charts/full-emoji-list.html

在支持 Unicode 的環境中,如現代的文本編輯器、瀏覽器等,你可以直接輸入 Emoji 字符來使用它們。許多操作系統都提供了便捷的 Emoji 輸入方法,例如在 Windows 系統中,按下 win + . 組合鍵可以打開 Emoji 選擇器;在 macOS 系統中,按下 Fn + E 組合鍵可以打開 Emoji 輸入菜單。

圖片圖片

不知道你有沒有發現,在不同系統/應用上,Emoji 長的都不太一樣,這是為什么呢?其實,Unicode 為每個 Emoji 分配了唯一的碼點,確保其在不同系統中代表相同的含義,但并沒有規定每個 Emoji 的樣式。因此,每個系統/應用都可以根據各自的設計風格對 Emoji 進行設計,所以就出現了多種風格的 Emoji。

圖片圖片

為了提高一致性,一些項目提供了標準化的 Emoji 集合,可以通過這些項目來自定義 Emoji 顯示,如 Twemoji:https://github.com/googlefonts/noto-emoji

需要格外注意的是:不同的文化對 Emoji 的理解和使用可能有所不同。例如,某些 Emoji 在特定文化中可能有特殊的含義或象征意義。因此,在國際化應用中,需要特別注意 Emoji 的使用,以避免誤解或冒犯。

Emoji 在前端的應用

表示

HTML

  • 直接插入 Emoji:可以在 HTML 文件中的任何文本位置直接插入 Emoji。
<p>今天天氣真好 ??</p>
  • 使用 Unicode 編碼:如果無法直接輸入 Emoji 或者希望使用其 Unicode 編碼,可以使用 Unicode 轉義序列。
<p>今天天氣真好 ?</p>

注意:&#x 后面跟隨的是 Emoji 的 Unicode 碼點的十六進制表示。例如,笑臉 ?? 的 Unicode 碼點是 U+1F60A,在 HTML 中表示為 &#x1F60A;。

CSS

  • 使用 content 屬性: 可以通過 CSS 的 ::before 或 ::after 偽元素以及 content 屬性來插入 Emoji。
.emoji-before::before {
  content: "??"; /* 直接插入 Emoji */
}

.emoji-after::after {
  content: "\1F60A"; /* 使用 Unicode 轉義序列 */
}

注意: 在 CSS 中使用 Unicode 轉義序列時,不需要 &#x 前綴,直接使用 \ 加上十六進制編碼即可。

由于 Emoji 是彩色字符,通常不需要額外的顏色設置。不過,可以通過調整字體大小來控制 Emoji 的顯示大小。

h1 {
    font-size: 2em; /* 將字體大小放大兩倍 */
}

JavaScript

在 JavaScript 中,可以通過以下方式來表示 Emoji:

  • 直接插入 Emoji: 在現代 JavaScript 環境中,可直接在字符串里使用 Emoji 字符。因為現代編輯器和瀏覽器廣泛支持 Unicode 字符,能正確識別和顯示 Emoji。
console.log('Hello ??'); // 輸出: Hello ??
  • 使用 Unicode 編碼: 每個 Emoji 都有對應的 Unicode 編碼,可通過 Unicode 編碼來表示 Emoji。基本多文種平面(BMP)內的 Emoji 用 \u 加 4 位十六進制編碼表示;超出 BMP 的 Emoji 需用代理對或 \u{} 語法表示。
// BMP 內的 Emoji
const heart = '\u2764'; 
console.log(heart);   // ?

// 超出 BMP 的 Emoji,使用代理對
const rocket = '\uD83D\uDE80'; 
console.log(rocket);  // ??

// 超出 BMP 的 Emoji,使用 \u{} 語法
const pizza = '\u{1F355}'; 
console.log(pizza);   // ??

獲取和設置碼點

  • 獲取碼點: 可以使用 codePointAt() 方法來獲取字符串中某個位置的 Unicode 碼點。
const smiley = '??';
console.log(smiley.codePointAt(0).toString(16)); // 輸出: 1f60a
  • 設置碼點: 可以使用 String.fromCodePoint() 方法從 Unicode 碼點創建字符串。
console.log(String.fromCodePoint(0x1F60A)); // 輸出: ??

字符串操作

問題

在 JavaScript 中處理 Emoji 時,尤其是涉及字符串操作,存在一些常見的問題。

  • 代理對: 在 JavaScript 里,字符串中的每個字符通常以 16 位(即 2 個字節)來表示,這遵循的是 UTF-16 編碼規則。不過,Emoji 字符比較特殊,部分 Emoji 字符的編碼超出了基本多文種平面(BMP),需要使用代理對來表示,也就是用兩個 16 位編碼單元來表示一個 Emoji 字符。因此,普通的 .length 屬性可能會返回不正確的字符數,因為它會將代理對視為兩個字符。
const emoji = '??';
console.log(emoji.length); // 輸出: 2 (而不是1)
  • 組合字符: 帶有修飾符的 Emoji 可能由多個碼點組成。例如,?????? 是由三個獨立的 Emoji 組合而成的。因此,在使用 .length計算長度時,得到的結果是不準確的。
const familyEmoji = '??????';
console.log(familyEmoji.length); // 輸出: 8 (而不是1)
  • 截斷問題: JavaScript 中的 slice、substring 或 substr 方法會按照 16 位編碼單元來截取字符串,當使用這些方式截斷包含 Emoji 的字符串時,若在截取過程中恰好截斷了一個代理對,就會產生亂碼。因為這些方法是無法正確處理代理對和組合字符的。
const emojiStr = '??????';
// 錯誤的截取,截斷了代理對
const wrongSubStr = emojiStr.slice(0, 1); 
console.log(wrongSubStr); // ?

內置 API:Intl.Segmenter

ES2021 提供了 Intl.Segmenter,可以解決上面的問題,它是 ECMAScript 國際化 API 的一部分,用于根據語言和區域設置對字符串進行分割。它可以將文本分割成有意義的單元,如單詞、句子或圖元簇,從而更好地處理多語言文本。

Intl.Segmenter 提供了以下分割方式:

  • Grapheme Cluster(圖元簇):將字符串分割為用戶感知的字符單位。這對于處理復雜的 Unicode 字符(如 Emoji 和組合字符)非常有用。
  • Word(單詞):將字符串分割為單詞。
  • Sentence(句子):將字符串分割為句子。

Intl.Segmenter 的基本用法如下:

  • 'en':指定語言環境。可以根據需要更改為其他語言環境,如 'zh' 或 'fr'。
  • { granularity: 'grapheme' }:指定分割粒度,可以是 'grapheme'、'word' 或 'sentence'。
const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });

在處理包含復雜 Unicode 字符(如 Emoji 和組合字符)的字符串時,確保準確計算字符數量。

const segmenter = new Intl.Segmenter([], { granularity: 'grapheme' });
const text = 'Hello ????♂? ??????!';
const segments = Array.from(segmenter.segment(text));
console.log(segments.length); // 輸出: 10

第三方庫:grapheme-splitter

對于上面這些問題,也可以使用grapheme-splitter庫來解決,它是一個用于處理 Unicode 字符串的 JavaScript 庫,專門用于將字符串分割成“圖元簇”。圖元簇是用戶感知的一個字符單位,即使它可能由多個 Unicode 碼點組成。例如,帶有膚色修飾符或性別修飾符的 Emoji 實際上是由多個碼點組成的,但用戶通常將其視為一個整體。

grapheme-splitter 的使用場景:

  • 統計字符數量:當需要準確統計字符串中用戶實際看到的字符個數時,例如在文本輸入框中限制字符數量,包含組合字符的字符串使用 .length 計算會不準確,使用 grapheme-splitter 可以得到正確結果。
import GraphemeSplitter from "grapheme-splitter";
const splitter = new GraphemeSplitter();

const str = '??????';
const length = splitter.countGraphemes(str);
console.log(length); // 輸出:1
  • 從字符串中提取特定位置的圖元簇:
import GraphemeSplitter from "grapheme-splitter";
const splitter = new GraphemeSplitter();

const text = 'Hello ????♂? ??????!';
const graphemes = splitter.splitGraphemes(text);
console.log(graphemes);  // 輸出:["H", "e", "l", "l", "o", " ", "????♂?", " ", "??????", "!"]

// 獲取第一個圖元簇
console.log(graphemes[0]); // 輸出: H

// 獲取第7個圖元簇(包含復雜的Emoji)
console.log(graphemes[5]); // 輸出: ????♂?

// 獲取最后一個圖元簇
console.log(graphemes[graphemes.length - 1]); // 輸出: !
  • 字符串截取:在截取字符串時,確保不會截斷組合字符,避免出現亂碼或不完整的字符顯示。
import GraphemeSplitter from "grapheme-splitter";
const splitter = new GraphemeSplitter();

const text = 'Hello ????♂? ??????!';
const graphemes = splitter.splitGraphemes(text);


// 截取前5個圖元簇
const firstFive = graphemes.slice(0, 5).join("");
console.log(firstFive); // 輸出: Hello

// 截取第6到第7個圖元簇
const middlePart = graphemes.slice(6, 7).join("");
console.log(middlePart); // 輸出: ????♂?

// 截取最后1個圖元簇
const lastFive = graphemes.slice(-2).join("");
console.log(lastFive); // 輸出: ??????!
  • 字符遍歷:按用戶感知的字符逐個遍歷字符串,對每個字符進行特定操作。
import GraphemeSplitter from "grapheme-splitter";
const splitter = new GraphemeSplitter();

const str = '????????????♂?';
const graphemes = splitter.splitGraphemes(str);
graphemes.forEach((grapheme) => {
    console.log(grapheme);
});

驗證

在處理 Emoji 時,驗證輸入是否包含有效的 Emoji 字符是一個常見的需求。這可以通過多種方式實現,包括正則表達式以及使用專門的庫來幫助識別和驗證 Emoji。

正則表達式

Emoji 是 Unicode 字符,因此可以使用正則表達式來匹配它們。然而,由于 Emoji 的種類繁多,并且新的 Emoji 不斷被添加到 Unicode 標準中,編寫一個全面的正則表達式可能會比較復雜。下面是一個例子:

const emojiRegex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?(?:\u200d(?:[^\ud800-\udfff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?)*/gu;

const text = "Hello ????♂? ??????! How are you?";

// 提取所有匹配的 Emoji
const matches = text.match(emojiRegex);

if (matches) {
    console.log('Matches:', matches); // 輸出: ["????♂?", "??????"]
} else {
    console.log('No emojis found.');
}

// 驗證是否包含 Emoji
const hasEmoji = emojiRegex.test(text);
console.log('Contains emoji:', hasEmoji); // 輸出: true

注意: 當使用正則表達式處理包含超出 BMP 的 Unicode 字符(如 Emoji)的字符串時,就需要使用 u 修飾符。u 修飾符的主要作用是開啟 Unicode 模式,讓正則表達式能夠正確處理超過 \uFFFF 的 Unicode 字符。在 JavaScript 里,字符串中的字符默認以 UTF-16 編碼存儲,基本多文種平面(BMP)內的字符可以用一個 16 位的編碼單元表示,但超出 BMP 的字符需要用兩個 16 位的編碼單元(代理對)來表示。在沒有 u 修飾符的情況下,正則表達式會將代理對拆分成兩個單獨的編碼單元進行處理;而使用 u 修飾符后,正則表達式能將代理對視為一個整體,從而正確匹配和處理這些字符。

第三方庫:emoji-regex

emoji-regex 是一個專門用于匹配 Emoji 的 JavaScript 庫。它可以準確地識別和匹配各種類型的 Emoji。

import emojiRegex from 'emoji-regex';
const regex = emojiRegex();

const text = "Hello ????♂? ??????! How are you?";
const matches = text.match(regex);

console.log(matches); // 輸出: ["??", "??", "\u200d", "♂", "\ufe0f", "??", "\u200d", "??", "\u200d", "??"]

Emoji 選擇器

Emoji 選擇器可幫助用戶方便地插入 Emoji 字符。它在許多應用(如聊天軟件、社交平臺、文本編輯器等)中廣泛使用。我們可以根據需要自定義 Emoji 選擇器(可以借助 emojibase 庫的數據來實現),也可以使用開源的 Emoji 選擇器,以下是一些比較熱門的 Emoji 選擇器(npm包名稱)。

  • emoji-mart:

圖片圖片

  • emoji-picker-react:

圖片圖片

  • vue3-emoji-picker:

圖片圖片

責任編輯:武曉燕 來源: 前端充電寶
相關推薦

2023-02-10 09:04:27

2020-02-18 16:20:03

Redis ANSI C語言日志型

2022-06-20 09:01:23

Git插件項目

2022-08-01 11:33:09

用戶分析標簽策略

2021-04-08 07:37:39

隊列數據結構算法

2023-09-11 08:13:03

分布式跟蹤工具

2020-08-03 10:00:11

前端登錄服務器

2023-10-17 08:15:28

API前后端分離

2020-07-03 08:21:57

Java集合框架

2024-09-23 08:00:00

消息隊列MQ分布式系統

2019-05-14 09:31:16

架構整潔軟件編程范式

2025-08-07 04:10:00

光模塊AI網絡

2018-05-22 08:24:50

PythonPyMongoMongoDB

2017-03-11 22:19:09

深度學習

2022-04-07 10:39:21

反射Java安全

2023-11-18 09:30:42

模型AI

2019-04-01 10:43:59

Linux問題故障

2022-07-06 12:07:06

Python函數式編程

2023-11-06 07:21:13

內存結構Jvm

2020-10-21 14:12:02

Single Sign
點贊
收藏

51CTO技術棧公眾號

亚洲人午夜色婷婷| 日韩成人中文字幕| 久久手机在线视频| 国产一级一区二区| 日韩美女视频中文字幕| 欧美91在线|欧美| 欧美日韩高清一区二区三区| 黄动漫在线免费观看| 中文字幕中文字幕在线一区 | 日韩毛片在线一区二区毛片| 久久夜色精品国产噜噜av| 日本久久高清视频| 日本欧美一区二区三区| 免费精品视频一区二区三区| 亚洲国产黄色| 国产成人免费电影| 激情六月综合| 国产精品免费一区二区三区| 欧美在线国产| 国产精品一区二区欧美黑人喷潮水| 亚洲综合中文| 精品乱色一区二区中文字幕| 欧美69视频| 麻豆亚洲一区| 久久精品国产99| 国产成人生活片| 成人av网站在线| 久久午夜夜伦鲁鲁一区二区| 久久网站最新地址| 97超碰在线资源站| 亚洲精品国产无套在线观| 天天噜天天色| 欧美唯美清纯偷拍| 91一区二区三区在线| 精品88久久久久88久久久| 丝袜诱惑一区二区| 欧美xxxx综合视频| 免费成人网www| 国产精品久久久一区二区三区| 美女日韩在线中文字幕| 日本一道在线观看| 久久久精品tv| 在线伊人免费视频| 欧美一卡二卡三卡| 久久99国产精品二区高清软件| 国模吧一区二区三区| 久久久久国产精品| 亚洲va韩国va欧美va精四季| 成人精品电影在线观看| 91精选福利| 欧美一区二区在线不卡| 国产第一亚洲| 国产精品中文在线| 热久久久久久久| 99riav视频| 在线亚洲高清视频| 日韩伦理三区| 国产精品久久久亚洲| 国产精品日韩精品欧美精品| 国内外成人激情免费视频| 国产亚洲精久久久久久| 国产在线三区| 一本色道久久综合亚洲精品小说| 欧美理伦片在线播放| 麻豆成人在线播放| 国产精品系列在线| 欧美69xxxx| 久久99亚洲热视| 欧美精品二区| 成人免费无码av| 欧美放荡的少妇| 白嫩白嫩国产精品| 久久精品国产综合精品| 91首页免费视频| 99reav在线| 美日韩在线视频| 亚洲欧美成人| eeuss鲁片一区| 日韩精品中文字幕在线播放| 国产免费久久| 日韩精品综合在线| 91久久精品一区二区| 久久视频免费| 一区二区成人国产精品 | 制服丝袜日韩国产| 成人精品毛片| 亚洲一区二区精品在线观看| 亚洲精品国产品国语在线app| 波多野结依一区| 国产欧美中文字幕| 成人一区二区三区视频在线观看| 性网站在线看| 欧美国产日韩在线| 黄色精品一二区| 尤物视频在线免费观看| 欧美激情精品久久久久久蜜臀| 日韩不卡手机在线v区| 特黄特色大片免费视频大全| 日韩一区二区三区xxxx| 久久精品导航| 男人的天堂在线免费视频| 欧美精品久久久久久久久| 男女性色大片免费观看一区二区 | 日本精品性网站在线观看| 国产jizzjizz一区二区| 在线观看h片| 91精品久久久久久久久久入口| 国产女人18毛片水真多成人如厕 | 7777在线视频| 91精品一区二区三区在线观看| jvid福利在线一区二区| 国产精品免费成人| 亚洲精品自拍偷拍| 天堂av在线一区| 一区二区高清不卡| 亚洲资源在线看| 亚洲国产日韩精品| 国产成人影院| 国产无遮挡又黄又爽免费软件| 中文字幕日韩免费视频| 激情综合网最新| h片在线观看视频免费免费| 久久涩涩网站| 欧美日韩电影在线| 亚洲伦理一区| 欧美a在线看| 欧美在线视频二区| 日韩亚洲欧美一区二区三区| 亚洲美洲欧洲综合国产一区| 牛牛澡牛牛爽一区二区| 亚洲自拍中文字幕| 91极品视觉盛宴| 影音先锋国产精品| av网站在线播放| 久久伊人一区| 亚洲福利影片在线| 国产一区999| 四虎精品在线观看| 蜜桃传媒一区二区三区| 久久中文字幕在线| 国产精品麻豆久久久| 视频小说一区二区| 最美情侣韩剧在线播放| 91精品久久久久久久久中文字幕| 欧美日韩国产在线| 国产婷婷精品| 伊人久久视频| 97视频在线免费播放| 久久久久久亚洲精品不卡| 最新国产成人在线观看| 精品一区av| 香蕉视频国产在线观看| 亚洲一区bb| 欧美国产激情18| 一区二区三区产品免费精品久久75| 日韩久久视频| 麻豆网站在线| 欧美做暖暖视频| 韩剧1988免费观看全集| 欧美日韩国产精品专区 | 久久青草伊人| 成人久久久久久久久| 日韩美女视频中文字幕| 欧美色道久久88综合亚洲精品| 国产日韩一区二区三区在线播放 | 日韩欧美一级在线| 久久99亚洲热视| 精品动漫一区二区三区| 性欧美videos另类喷潮| 国产不卡123| 午夜激情在线观看视频| 国产一区深夜福利| 精品99999| 国产精品国产a| 国产情侣一区| 成人激情久久| 搞黄视频在线观看| 国产白丝袜美女久久久久| 国产精品白嫩美女在线观看| 欧美精品在线一区二区三区| 国产1区2区3区精品美女| 小嫩嫩12欧美| 超碰在线97国产| 1024欧美极品| 日本不卡一二三区| 97精品国产91久久久久久| 欧美色图在线观看| 91免费观看国产| 亚洲人体大胆视频| 日韩中文一区二区| 欧美精品电影| 国内外成人免费在线视频| 精品久久久久久综合日本| 欧美日韩第一视频| 欧洲中文字幕精品| 久久久久久久久97黄色工厂| 99视频精品| 欧美高清视频看片在线观看| a级影片在线| 亚洲kkk444kkk在线观看|