一個(gè)emoji引發(fā)的思考

轉(zhuǎn)自張譯文

從畢業(yè)以來(lái),基本就一直在做移動(dòng)端策治,但是一直就關(guān)于移動(dòng)端的開(kāi)發(fā)脓魏,各種適配問(wèn)題的解決,在日常搬磚中處理了就過(guò)了通惫,也沒(méi)有把東西都沉淀下來(lái)茂翔,覺(jué)得甚是寒顏。現(xiàn)就一個(gè)小bug履腋,讓我們來(lái)了解一下我們天天都在用的emoji檩电,對(duì)于開(kāi)發(fā)來(lái)說(shuō),是一個(gè)怎么樣的存在府树。

背景

之前在做一個(gè)留言功能時(shí)俐末,發(fā)現(xiàn)在其中一臺(tái)安卓5.0的手機(jī)上,輸入emoji糊掉了奄侠,成了如下這樣的情況?

與是我又試了好幾個(gè)手機(jī)卓箫,ios都沒(méi)有問(wèn)題,甚至一臺(tái)安卓機(jī)中之霸(安卓4.0)垄潮,隨便進(jìn)個(gè)頁(yè)面都要加載十幾秒的手機(jī)都沒(méi)有問(wèn)題烹卒,是亂碼了嗎闷盔?

為啥emoji會(huì)出現(xiàn)亂碼呢?相信很多人都遇到過(guò)關(guān)于emoji的問(wèn)題旅急,比如輸入emoji逢勾,傳給后端,再經(jīng)過(guò)一系列操作后從接口中取到后端返回的emoji字符就亂了藐吮。又比如為了限制輸入字?jǐn)?shù)溺拱,給字符做截?cái)鄷r(shí)出現(xiàn)的問(wèn)題。

初步懷疑是編碼問(wèn)題谣辞,那我們就來(lái)看看emoji究竟是何方神圣迫摔。

emoji的歷史

emoji對(duì)于我們來(lái)說(shuō)并不陌生,我們很早就開(kāi)始接觸它了泥从。emoji這個(gè)詞來(lái)源于日語(yǔ)里的“絵文字”(假名為“えもじ”句占,讀音即emoji)。它是1999年躯嫉,當(dāng)時(shí)還在日本無(wú)線運(yùn)營(yíng)商N(yùn)TT DoCoMo工作的Shigetaka Kurita(栗田穣崇)發(fā)明的纱烘。

emoji的編碼

emoji雖然看上去是一個(gè)有顏色有形狀的表情,但它屬于計(jì)算機(jī)中的字符祈餐。在計(jì)算機(jī)中擂啥,我們把文字、標(biāo)點(diǎn)符號(hào)昼弟、圖形符號(hào)、數(shù)字等統(tǒng)一稱(chēng)為字符奕筐,由字符組成的集合舱痘,我們稱(chēng)為字符集。為了讓計(jì)算機(jī)識(shí)別字符集里的字符离赫,我們?cè)O(shè)計(jì)了一套字符集編碼規(guī)則芭逝,比如ASCII碼,由于ASCII只規(guī)定了128個(gè)字符的編碼渊胸,隨著計(jì)算機(jī)的發(fā)展旬盯,人們意識(shí)到這些編碼顯然是不夠的,為了統(tǒng)一世界上的所有字符翎猛,誕生出了Unicode字符集胖翰,而emoji字符就是Unicode字符集中的一部分。

Unicode

Unicode從0開(kāi)始切厘,為每個(gè)符號(hào)指定一個(gè)編號(hào)萨咳,稱(chēng)做"碼點(diǎn)",如U+0000疫稿,U+表示緊跟在后面的十六進(jìn)制數(shù)是Unicode的碼點(diǎn)培他。Unicode只規(guī)定了每個(gè)字符的碼點(diǎn)鹃两,到底用什么樣的字節(jié)序表示這個(gè)碼點(diǎn)灯荧,就涉及到編碼方法啊犬,比如我們html上常用的UTF-8。關(guān)于不同的編碼方法怎么表示Unicode抄淑,以及JavaScript是怎么處理Unicode猛遍,這里就不詳細(xì)闡述了馋记,可參考Unicode與JavaScript詳解?鏈接地址:http://www.ruanyifeng.com/blog/2014/12/unicode.html

所以emoji作為unicode,那在計(jì)算機(jī)上是怎么顯示的螃壤?

之前我在一微信群里@我一朋友抗果,結(jié)果出現(xiàn)了下面的情況。

@符號(hào)跑右邊去了奸晴,當(dāng)時(shí)覺(jué)得很奇怪冤馏,后來(lái)了解到,這是阿拉伯文寄啼,因?yàn)榘⒗牡臅?shū)寫(xiě)規(guī)則是從右向左逮光,所以@符號(hào)跑到右邊去了,可見(jiàn)微信對(duì)不同unicode字符排版做的兼容還挺好墩划。再比如這幾個(gè)字符涕刚,熱?得?字?出?汗?了?。

這就涉及到了復(fù)雜文字編排(Complex text layout乙帮,縮寫(xiě):CTL)杜漠。要求復(fù)雜文字編排以適當(dāng)顯示的書(shū)寫(xiě)系統(tǒng)稱(chēng)為復(fù)雜文本,比如阿拉伯文字察净、婆羅米系文字的天城文驾茴、泰文等。

拿泰文來(lái)說(shuō)氢卡,根據(jù)拼寫(xiě)規(guī)則锈至,泰文可形象地分為鞋子字符、主體字符译秦、帽子字符峡捡、聲調(diào)字符等。泰文的每個(gè)基本字符對(duì)應(yīng)一個(gè)unicode碼筑悴,人們?cè)谳斎攵鄠€(gè)基本字符時(shí)们拙,新輸入的字符與之前的字符做匹配,如果可以組合阁吝,則這時(shí)前面的輸入就拼合成了一個(gè)泰文字符然后顯示出來(lái)睛竣。

薩瓦迪卡~

英文也是,我們?cè)谳斎胗⑽臅r(shí)會(huì)習(xí)慣以空格來(lái)拆分前后單詞,你如果輸入一串連續(xù)的英文字母求摇,計(jì)算機(jī)在識(shí)別上也會(huì)有困難射沟。phpisthebestlanguageintheworld(手動(dòng)滑稽臉)這句話(huà)就很有爭(zhēng)議J庹摺!

人為可以輕松識(shí)別一個(gè)泰文是否拼寫(xiě)正確验夯,但是計(jì)算機(jī)在顯示時(shí)就很難判斷猖吴。

像泰文這種特殊合成字符的本質(zhì),你無(wú)法避免人們?cè)谟?jì)算機(jī)上都會(huì)有哪些奇妙的創(chuàng)造挥转。

于是乎海蔽,不同字符之間的組合,就誕生出了流行的顏文字:

???????

???????-???????????

(???^???)

???(?σ????? ?σ????)·??

?(???????)??

而字符的顯示绑谣,還有一個(gè)影響就是字體党窜,在瀏覽器中,如果對(duì)應(yīng)的編碼在字體文件中為空借宵,一般會(huì)展示成□□□□幌衣,這樣至少不會(huì)影響排版,但是unicode作為萬(wàn)國(guó)碼實(shí)在太龐大了壤玫,在一些字體里豁护,對(duì)一些特殊字符還是會(huì)產(chǎn)生一些錯(cuò)誤的排版,唉?~真?是惆?悵~~

對(duì)于emoji來(lái)說(shuō)欲间,它雖然也是一種特殊字符楚里,但它并不屬于復(fù)雜文本,并且我是通過(guò)移動(dòng)終端規(guī)范輸入猎贴,排版也不會(huì)有什么問(wèn)題班缎。我設(shè)置的font-family在其他手機(jī)上是好的也說(shuō)明,這些字體對(duì)輸入的emoji也是支持的她渴,出問(wèn)題的終端上达址,非emoji的字體正常顯示,那暫時(shí)可以排除字體對(duì)emoji的影響了惹骂。

回歸問(wèn)題

到這里苏携,還沒(méi)有解決我的問(wèn)題做瞪。本來(lái)以為是常見(jiàn)問(wèn)題对粪,比如數(shù)據(jù)提交時(shí)或者數(shù)據(jù)庫(kù)儲(chǔ)存的編碼問(wèn)題∽芭睿可是著拭,我也沒(méi)傳給后端啊牍帚!我剛在自己的頁(yè)面上輸入顯示就成這樣了儡遮!

?我一氣之下瘋狂亂點(diǎn),發(fā)現(xiàn)不同的表情對(duì)應(yīng)的這些小蟲(chóng)長(zhǎng)得還不一樣暗赶,于是鄙币,我決定把它放大看一看

?這不就是表情么肃叶,只是因?yàn)槟承┰蚩瓷先ケ粔嚎s了。我的表情啊十嘿,你到底是經(jīng)歷了什么才變得如此面目全非因惭。我一定要找到毀你容的真兇。

先分析一下表象绩衷,emoji的顯示被截?cái)啾哪А嚎s。為什么被壓縮咳燕?回歸場(chǎng)景勿决,移動(dòng)端切圖,那么移動(dòng)端的多終端適配招盲,可不可能是問(wèn)題的原因低缩?

切圖是UI給的以iphone6的屏幕寬度為準(zhǔn)的750px2倍視覺(jué)稿,組內(nèi)方案選擇參考了手淘的flexible宪肖。具體原理和這次主題無(wú)關(guān)表制,我就不在這里闡述了。關(guān)于移動(dòng)端多端適配方案的原理詳細(xì)控乾,可以參考?手淘H5頁(yè)面的終端適配

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

那么哪些代碼是影響emoji縮放的代碼呢么介?最先想到的是,我的emoji在輸入框里面蜕衡,設(shè)置了font-size壤短,這個(gè)font-size的值是rem, 那會(huì)不會(huì)是某些安卓系統(tǒng)emoji對(duì)rem支持不好?于是我換成px慨仿,依然如此久脯。

那么頁(yè)面上還有哪兒還有會(huì)影響縮放呢?于是定位到了這里镰吆。

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

viewport是我們?cè)O(shè)備屏幕上用來(lái)顯示網(wǎng)頁(yè)的區(qū)域帘撰,在移動(dòng)端上,viewport一般都是大于瀏覽器可視區(qū)域万皿。

理論上摧找,移動(dòng)端有三個(gè)viewport。

layout viewport:移動(dòng)瀏覽器為了讓所有網(wǎng)站正常顯示(包括那些PC的頁(yè)面)牢硅,把默認(rèn)的viewport設(shè)為了一個(gè)較寬值蹬耘,這個(gè)值一般都是大于移動(dòng)端可視區(qū)(比如iPhone 980px)。也就是document.documentElement.clientWidth

visual viewport:代表瀏覽器可視區(qū)域的大小减余。也就是window.innerWidth

ideal viewport:能完美適配移動(dòng)設(shè)備的viewport综苔,用戶(hù)不需要縮放和橫向滾動(dòng)條就能完美看到網(wǎng)頁(yè)內(nèi)容,并且文字圖片,在不同分辨率屏幕下顯示出來(lái)太小應(yīng)該是差不多的(比如iPhone的ideal viewport寬度是320px)

關(guān)于各個(gè)設(shè)備的ideal viewport 可以從這里查詢(xún)如筛,鏈接地址:http://viewportsizes.com/

所以我們利用meta標(biāo)簽堡牡,設(shè)置viewport的寬度等于設(shè)備的寬度,并且不允許用戶(hù)手動(dòng)縮放。讓viewport的寬度等于設(shè)備的寬度杨刨,這個(gè)應(yīng)該就是我們想要的理想寬度悴侵。

實(shí)際上,只設(shè)置initial-scale=1拭嫁,我們也能把當(dāng)前的viewport寬度變成ideal viewport的寬度(這里不考慮iphone下不同dpr的縮放)可免,因?yàn)檫@個(gè)縮放就是相對(duì)于ideal viewport來(lái)進(jìn)行縮放的。當(dāng)同時(shí)設(shè)置了width與initial-scale=1做粤,瀏覽器會(huì)選擇兩者中較大的那個(gè)值浇借。

說(shuō)了這么多,那么我的問(wèn)題出在哪兒呢怕品?猜想是不是該安卓版本對(duì)設(shè)置width和initial-scale會(huì)有一些意想不到的問(wèn)題妇垢,于是我去掉了width=device-width,保留initial-scale=1等屬性肉康,結(jié)果emoji竟然好了闯估。

所以我遇到的情況就是,同時(shí)設(shè)置了width=device-width和initial-scale=1吼和,會(huì)造成某些廠商手機(jī)的安卓5.0(目前只遇到這個(gè))emoji被拉伸涨薪,去掉width=device-width,(不寫(xiě)width=device-width也就是windows phone上的IE無(wú)論是橫豎屏都把寬度設(shè)為豎屏?xí)rideal viewport寬度炫乓,個(gè)人覺(jué)得這個(gè)無(wú)傷大雅)刚夺,至于為什么會(huì)這樣,我暫時(shí)只能深入到這啦 (╥╯^╰╥)

結(jié)論

每一個(gè)emoji末捣,就是一個(gè)Unicode字符侠姑,由統(tǒng)一碼聯(lián)盟(The Unicode Consortium)來(lái)投票選拔和公布,世界各地的人們可以向聯(lián)盟提交 emoji 提案箩做。而統(tǒng)一碼聯(lián)盟的 emoji 規(guī)范莽红,只是定義了某個(gè)字符的語(yǔ)義,再由 Emojipedia 這個(gè)網(wǎng)站對(duì) emoji 進(jìn)行描述表達(dá)邦邦,最后允許大家按照對(duì)描述的理解安吁,自由地去設(shè)計(jì)圖案。

所以不同的廠商以及不同的系統(tǒng)圃酵,甚至瀏覽器柳畔、瀏覽器版本以及系統(tǒng)字體等馍管,對(duì)emoji的支持程度與兼容性是不一樣的郭赐。比如同一個(gè)emoji笑臉表情,在ios和安卓上顯示的效果也不一樣。為了統(tǒng)一emoji表情捌锭,很多公司都有自己的一套emoji mapping俘陷,來(lái)做Unicode碼與emoji表情的映射。

碎碎念

移動(dòng)端開(kāi)發(fā)總會(huì)遇到各種問(wèn)題观谦,有時(shí)候做兼容也會(huì)遇到無(wú)法完全兼容兩頭的情況拉盾,這時(shí)只能放棄受眾更小,選擇兼容影響面豁状、嚴(yán)重性更大的方案了捉偏。在解決問(wèn)題的有時(shí)候深究下去,也會(huì)收獲很多泻红。

更多文章

Emoji 那些事兒


原文鏈接

關(guān)注公眾號(hào)【grain先森】夭禽,回復(fù)關(guān)鍵詞 【18福利】,獲取為你準(zhǔn)備的年終福利谊路,更多關(guān)鍵詞玩法期待你的探索~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末讹躯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子缠劝,更是在濱河造成了極大的恐慌潮梯,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惨恭,死亡現(xiàn)場(chǎng)離奇詭異秉馏,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)脱羡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)沃饶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人轻黑,你說(shuō)我怎么就攤上這事糊肤。” “怎么了氓鄙?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵馆揉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我抖拦,道長(zhǎng)升酣,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任态罪,我火速辦了婚禮噩茄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘复颈。我一直安慰自己绩聘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著凿菩,像睡著了一般机杜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衅谷,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天椒拗,我揣著相機(jī)與錄音,去河邊找鬼获黔。 笑死蚀苛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的玷氏。 我是一名探鬼主播枉阵,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼预茄!你這毒婦竟也來(lái)了兴溜?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤耻陕,失蹤者是張志新(化名)和其女友劉穎拙徽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體诗宣,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡膘怕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了召庞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岛心。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖篮灼,靈堂內(nèi)的尸體忽然破棺而出忘古,到底是詐尸還是另有隱情,我是刑警寧澤诅诱,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布髓堪,位于F島的核電站,受9級(jí)特大地震影響娘荡,放射性物質(zhì)發(fā)生泄漏干旁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一炮沐、第九天 我趴在偏房一處隱蔽的房頂上張望争群。 院中可真熱鬧,春花似錦大年、人聲如沸换薄。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)专控。三九已至,卻和暖如春遏餐,著一層夾襖步出監(jiān)牢的瞬間伦腐,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工失都, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柏蘑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓粹庞,卻偏偏與公主長(zhǎng)得像咳焚,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子庞溜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容