由一個emoji引起的思考

由一個emoji引起的思考

從畢業以來,基本就一直在作移動端,可是一直就關於移動端的開發,各類適配問題的解決,在平常搬磚中處理了就過了,也沒有把東西都沉澱下來,以爲甚是寒顏。現就一個小bug,讓咱們來了解一下咱們每天都在用的emoji,對於開發來講,是一個怎麼樣的存在。php

背景

以前在作一個留言功能時,發如今其中一臺安卓5.0的手機上,輸入emoji糊掉了,成了以下這樣的狀況
html

這是skr啥玩意兒呀,怎麼看上去像某白色幼蟲。html5

與是我又試了好幾個手機,ios都沒有問題,甚至一臺安卓機中之霸(安卓4.0),隨便進個頁面都要加載十幾秒的手機都沒有問題,是亂碼了嗎?ios

爲啥emoji會出現亂碼呢?相信不少人都遇到過關於emoji的問題,好比輸入emoji,傳給後端,再通過一系列操做後從接口中取到後端返回的emoji字符就亂了。又好比爲了限制輸入字數,給字符作截斷時出現的問題。數據庫

初步懷疑是編碼問題,那咱們就來看看emoji到底是何方神聖。windows

emoji的歷史

emoji對於咱們來講並不陌生,咱們很早就開始接觸它了。emoji這個詞來源於日語裏的「絵文字」(假名爲「えもじ」,讀音即emoji)。它是1999年,當時還在日本無線運營商NTT DoCoMo工做的Shigetaka Kurita(慄田穣崇)發明的。後端

emoji的編碼

emoji雖然看上去是一個有顏色有形狀的表情,但它屬於計算機中的字符。在計算機中,咱們把文字、標點符號、圖形符號、數字等統一稱爲字符,由字符組成的集合,咱們稱爲字符集。爲了讓計算機識別字符集裏的字符,咱們設計了一套字符集編碼規則,好比ASCII碼,因爲ASCII只規定了128個字符的編碼,隨着計算機的發展,人們意識到這些編碼顯然是不夠的,爲了統一世界上的全部字符,誕生出了Unicode字符集,而emoji字符就是Unicode字符集中的一部分。瀏覽器

Unicode

Unicode從0開始,爲每一個符號指定一個編號,稱作"碼點",如U+0000,U+表示緊跟在後面的十六進制數是Unicode的碼點。Unicode只規定了每一個字符的碼點,到底用什麼樣的字節序表示這個碼點,就涉及到編碼方法,好比咱們html上經常使用的UTF-8。關於不一樣的編碼方法怎麼表示Unicode,以及JavaScript是怎麼處理Unicode,這裏就不詳細闡述了,可參考Unicode與JavaScript詳解
連接地址:http://www.ruanyifeng.com/blog/2014/12/unicode.html微信

因此emoji做爲unicode,那在計算機上是怎麼顯示的?app

以前我在一微信羣裏@我一朋友,結果出現了下面的狀況。

@符號跑右邊去了,當時以爲很奇怪,後來瞭解到,這是阿拉伯文,由於阿拉伯文的書寫規則是從右向左,因此@符號跑到右邊去了,可見微信對不一樣unicode字符排版作的兼容還挺好。再好比這幾個字符,熱҈得҈字҈出҈汗҈了҈。

這就涉及到了複雜文字編排(Complex text layout,縮寫:CTL)。要求複雜文字編排以適當顯示的書寫系統稱爲複雜文本,好比阿拉伯文字、婆羅米系文字的天城文、泰文等。

拿泰文來講,根據拼寫規則,泰文可形象地分爲鞋子字符、主體字符、帽子字符、聲調字符等。泰文的每一個基本字符對應一個unicode碼,人們在輸入多個基本字符時,新輸入的字符與以前的字符作匹配,若是能夠組合,則這時前面的輸入就拼合成了一個泰文字符而後顯示出來。

薩瓦迪卡~

英文也是,咱們在輸入英文時會習慣以空格來拆分先後單詞,你若是輸入一串連續的英文字母,計算機在識別上也會有困難。phpisthebestlanguageintheworld(手動滑稽臉)這句話就頗有爭議!!

人爲能夠輕鬆識別一個泰文是否拼寫正確,可是計算機在顯示時就很難判斷。

像泰文這種特殊合成字符的本質,你沒法避免人們在計算機上都會有哪些奇妙的創造。

因而乎,不一樣字符之間的組合,就誕生出了流行的顏文字:

ฅ՞•ﻌ•՞ฅ

ʕ•̼͛͡•ʕ-̺͛͡•ʔ•̮͛͡•ʔ

(⑉꒦ິ^꒦ິ⑉)

₊˚‧(๑σ̴̶̷̥́ ₃σ̴̶̷̀)·˚₊

୧(๑•̀⌄•́๑)૭✧

而字符的顯示,還有一個影響就是字體,在瀏覽器中,若是對應的編碼在字體文件中爲空,通常會展現成□□□□,這樣至少不會影響排版,可是unicode做爲萬國碼實在太龐大了,在一些字體裏,對一些特殊字符仍是會產生一些錯誤的排版,唉҈~真҈是惆҈悵~~

對於emoji來講,它雖然也是一種特殊字符,但它並不屬於複雜文本,而且我是經過移動終端規範輸入,排版也不會有什麼問題。我設置的font-family在其餘手機上是好的也說明,這些字體對輸入的emoji也是支持的,出問題的終端上,非emoji的字體正常顯示,那暫時能夠排除字體對emoji的影響了。

迴歸問題

到這裏,尚未解決個人問題。原本覺得是常見問題,好比數據提交時或者數據庫儲存的編碼問題。但是,我也沒傳給後端啊!我剛在本身的頁面上輸入顯示就成這樣了!

可惡,這個鍋甩不動了。仍是得本身解決,我input框剛輸入,本地看到就亂了,看來仍是本身的問題。

我一氣之下瘋狂亂點,發現不一樣的表情對應的這些小蟲長得還不同,因而,我決定把它放大看一看

這不就是表情麼,只是由於某些緣由看上去被壓縮了。個人表情啊,你究竟是經歷了什麼才變得如此面目全非。我必定要找到毀你容的真兇。

先分析一下表象,emoji的顯示被截斷、壓縮。爲何被壓縮?迴歸場景,移動端切圖,那麼移動端的多終端適配,可不多是問題的緣由?

切圖是UI給的以iphone6的屏幕寬度爲準的750px2倍視覺稿,組內方案選擇參考了手淘的flexible。具體原理和此次主題無關,我就不在這裏闡述了。關於移動端多端適配方案的原理詳細,能夠參考
手淘H5頁面的終端適配

連接地址: https://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html

那麼哪些代碼是影響emoji縮放的代碼呢?最早想到的是,個人emoji在輸入框裏面,設置了font-size,這個font-size的值是rem,
那會不會是某些安卓系統emoji對rem支持很差?因而我換成px,依然如此。

那麼頁面上還有哪兒還有會影響縮放呢?因而定位到了這裏。

<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=0,width=device-width" />

viewport是咱們設備屏幕上用來顯示網頁的區域,在移動端上,viewport通常都是大於瀏覽器可視區域。

理論上,移動端有三個viewport。

  • layout viewport:移動瀏覽器爲了讓全部網站正常顯示(包括那些PC的頁面),把默認的viewport設爲了一個較寬值,這個值通常都是大於移動端可視區(好比iPhone 980px)。也就是document.documentElement.clientWidth
  • visual viewport:表明瀏覽器可視區域的大小。也就是window.innerWidth
  • ideal viewport:能完美適配移動設備的viewport,用戶不須要縮放和橫向滾動條就能完美看到網頁內容,而且文字圖片,在不一樣分辨率屏幕下顯示出來過小應該是差很少的(好比iPhone的ideal viewport寬度是320px)

關於各個設備的ideal viewport 能夠從這裏查詢,連接地址:http://viewportsizes.com/

因此咱們利用meta標籤,設置viewport的寬度等於設備的寬度,而且不容許用戶手動縮放。讓viewport的寬度等於設備的寬度,這個應該就是咱們想要的理想寬度。

實際上,只設置initial-scale=1,咱們也能把當前的viewport寬度變成ideal viewport的寬度(這裏不考慮iphone下不一樣dpr的縮放),由於這個縮放就是相對於ideal viewport來進行縮放的。當同時設置了width與initial-scale=1,瀏覽器會選擇二者中較大的那個值。

說了這麼多,那麼個人問題出在哪兒呢?猜測是否是該安卓版本對設置width和initial-scale會有一些意想不到的問題,因而我去掉了width=device-width,保留initial-scale=1等屬性,結果emoji居然好了。

因此我遇到的狀況就是,同時設置了width=device-width和initial-scale=1,會形成某些廠商手機的安卓5.0(目前只遇到這個)emoji被拉伸,去掉width=device-width,(不寫width=device-width也就是windows phone上的IE不管是橫豎屏都把寬度設爲豎屏時ideal viewport寬度,我的以爲這個無傷大雅),至於爲何會這樣,我暫時只能深刻到這啦 (╥╯^╰╥)

結論

每個emoji,就是一個Unicode字符,由統一碼聯盟(The Unicode Consortium)來投票選拔和公佈,世界各地的人們能夠向聯盟提交 emoji 提案。而統一碼聯盟的 emoji 規範,只是定義了某個字符的語義,再由 Emojipedia 這個網站對 emoji 進行描述表達,最後容許你們按照對描述的理解,自由地去設計圖案。

因此不一樣的廠商以及不一樣的系統,甚至瀏覽器、瀏覽器版本以及系統字體等,對emoji的支持程度與兼容性是不同的。好比同一個emoji笑臉表情,在ios和安卓上顯示的效果也不同。爲了統一emoji表情,不少公司都有本身的一套emoji mapping,來作Unicode碼與emoji表情的映射。

碎碎念

移動端開發總會遇到各類問題,有時候作兼容也會遇到沒法徹底兼容兩頭的狀況,這時只能放棄受衆更小,選擇兼容影響面、嚴重性更大的方案了。在解決問題的有時候深究下去,也會收穫不少。

相關文章
相關標籤/搜索