無聊做了個 web 版的功能跟微信里面那個差不多的通訊錄朽基。
這個通訊錄現(xiàn)在長這個樣子:
以后可能就是這個樣子了(我不保證):
如果我最后放棄改進(jìn)它,你可以在這里找到源碼坦康,然后自己作修改猛铅。
這件事情的由來是寇窑,公司的設(shè)計師在之前的項目里想實現(xiàn)一個跟微信通訊錄一樣的頁面。我沒多少把握能在 web 端實現(xiàn)跟微信原生一樣的功能效果:可以想象東西做出來能覆蓋微信原生 80% 的功能慕的,但剩下的 20% 會被設(shè)計師挑刺當(dāng)成是 bug 阎肝,(比如姓氏的正確分類,比如多個同姓的人的先后排序肮街,比如多音字的處理风题,比如姓氏首字母切換的效果),要實現(xiàn)這 20% 的功能效果很費力氣。所以當(dāng)時就明說要做到一模一樣有困難沛硅,要么多給我點時間做眼刃,要么做一個十分簡單的帶個搜索功能的列表。最終選了后者摇肌。
這周處于迭代中間擂红,有點空閑時間,回想這個通訊錄功能围小,感覺可以做做昵骤。于是先到網(wǎng)上搜搜有沒有現(xiàn)成可靠的插件,發(fā)現(xiàn)竟然沒有肯适。
為什么這個功能會沒有人做呢变秦?忽然就產(chǎn)生自己來做一個的想法。要是做出來能用框舔,也是挺好的蹦玫。
這個功能(或者說是前端插件),首先是要方便 Rails 用戶使用雨饺,假設(shè)有一個不怎么懂前端的后端工程師钳垮,他只需要做一件事:提供一個聯(lián)系人數(shù)組,每個元素有 id/name/url 等等屬性就行额港。其余的事情交給這個插件饺窿。
然后我打算只用原生 javascript 實現(xiàn)所有的功能。這樣可以練習(xí)一下在沒有 jQuery/underscore 的情況下寫代碼移斩。
然后是把這個功能做正確:
- 聯(lián)系人按姓名正確分類
- 點索引要跳轉(zhuǎn)到正確的分類
- 當(dāng)前類別要在頂欄顯示
- 要有檢索過濾功能
以上目標(biāo)在動手前先寫下來肚医,然后一個個地實現(xiàn),這樣在斷斷續(xù)續(xù)的開發(fā)中也不會亂了優(yōu)先級向瓷。
真正動手時遇到幾個問題:
- 把中文姓氏正確分類
最初想法是找一個常用漢字與拼音一一對應(yīng)的哈希表肠套,遇到中文只需要查查表就行,雖然要引入大約十幾KB的數(shù)據(jù)猖任,但查表時間復(fù)雜度低你稚。可惜找了一圈沒找到合適的朱躺。
后來在 ruby-china 論壇找到一個聰明的方法刁赖,用幾行代碼就可以找到中文字的拼音首字母。我在以下幾個環(huán)境測試了下都沒有問題:
iOS 10 的 safari
iOS 10 的微信长搀,版本 6.3.30
android 5.0 的 chrome 宇弛, 版本 51
android 5.0 的微信,版本 6.3.30
點擊索引跳轉(zhuǎn)到相應(yīng)類別
這個用 html 原生的 anchor 實現(xiàn)源请,靈感來自 MDN 枪芒。實時更新當(dāng)前類別
要隨著頁面滾動更新頂欄的當(dāng)前類別彻况,不可避免要監(jiān)聽頁面的 scroll 事件。 scroll 事件會在頁面滾動過程中被頻繁觸發(fā)舅踪,可以用 underscore 的 throttle 來限制因事件觸發(fā)而調(diào)用其他方法的頻率纽甘,但我不想引入 underscore 。
在 MDN 上看到優(yōu)化后的監(jiān)聽 scroll 事件的方式硫朦,思路是利用 requestAnimationFrame 方法設(shè)置開關(guān)贷腕,這個方法會在瀏覽器渲染下一幀前調(diào)用。也就是說可以利用它使得由 scroll 事件觸發(fā)執(zhí)行的事件在每一幀都只被執(zhí)行一次咬展。圖標(biāo)
實現(xiàn)搜索功能才發(fā)現(xiàn)沒有搜索常用的“放大鏡”圖標(biāo)泽裳,無論是使用字體圖標(biāo)還是 svg/png 圖標(biāo),都意味著又得引入別的資源破婆′套埽看樣子這個圖標(biāo)不就是個圓圈加根棍子么?自己動手用CSS畫祷舀。
我大致想了下未來這個插件會變成怎樣瀑梗,一是要把UI做得跟微信差不多,現(xiàn)在的太樸素了點裳扯。
然后對同屬一個類別下的聯(lián)系人排序抛丽。排序是個有意思的工作,要選那些可以實現(xiàn)快速插入新元素的算法饰豺。
不過在此之前亿鲜,得先寫一篇介紹這個插件的文章,宣傳一下這個好東西冤吨。我現(xiàn)在很想在付出更大努力前蒿柳,想辦法知道值不值得。