无聊做了个 web 版的功能跟微信里面那个差不多的通讯录。
这个通讯录现在长这个样子:
以后可能就是这个样子了(我不保证):
如果我最后放弃改进它,你可以在这里找到源码,然后自己作修改。
这件事情的由来是,公司的设计师在之前的项目里想实现一个跟微信通讯录一样的页面。我没多少把握能在 web 端实现跟微信原生一样的功能效果:可以想象东西做出来能覆盖微信原生 80% 的功能,但剩下的 20% 会被设计师挑刺当成是 bug ,(比如姓氏的正确分类,比如多个同姓的人的先后排序,比如多音字的处理,比如姓氏首字母切换的效果),要实现这 20% 的功能效果很费力气。所以当时就明说要做到一模一样有困难,要么多给我点时间做,要么做一个十分简单的带个搜索功能的列表。最终选了后者。
这周处于迭代中间,有点空闲时间,回想这个通讯录功能,感觉可以做做。于是先到网上搜搜有没有现成可靠的插件,发现竟然没有。
为什么这个功能会没有人做呢?忽然就产生自己来做一个的想法。要是做出来能用,也是挺好的。
这个功能(或者说是前端插件),首先是要方便 Rails 用户使用,假设有一个不怎么懂前端的后端工程师,他只需要做一件事:提供一个联系人数组,每个元素有 id/name/url 等等属性就行。其余的事情交给这个插件。
然后我打算只用原生 javascript 实现所有的功能。这样可以练习一下在没有 jQuery/underscore 的情况下写代码。
然后是把这个功能做正确:
- 联系人按姓名正确分类
- 点索引要跳转到正确的分类
- 当前类别要在顶栏显示
- 要有检索过滤功能
以上目标在动手前先写下来,然后一个个地实现,这样在断断续续的开发中也不会乱了优先级。
真正动手时遇到几个问题:
- 把中文姓氏正确分类
最初想法是找一个常用汉字与拼音一一对应的哈希表,遇到中文只需要查查表就行,虽然要引入大约十几KB的数据,但查表时间复杂度低。可惜找了一圈没找到合适的。
后来在 ruby-china 论坛找到一个聪明的方法,用几行代码就可以找到中文字的拼音首字母。我在以下几个环境测试了下都没有问题:
iOS 10 的 safari
iOS 10 的微信,版本 6.3.30
android 5.0 的 chrome , 版本 51
android 5.0 的微信,版本 6.3.30
点击索引跳转到相应类别
这个用 html 原生的 anchor 实现,灵感来自 MDN 。实时更新当前类别
要随着页面滚动更新顶栏的当前类别,不可避免要监听页面的 scroll 事件。 scroll 事件会在页面滚动过程中被频繁触发,可以用 underscore 的 throttle 来限制因事件触发而调用其他方法的频率,但我不想引入 underscore 。
在 MDN 上看到优化后的监听 scroll 事件的方式,思路是利用 requestAnimationFrame 方法设置开关,这个方法会在浏览器渲染下一帧前调用。也就是说可以利用它使得由 scroll 事件触发执行的事件在每一帧都只被执行一次。图标
实现搜索功能才发现没有搜索常用的“放大镜”图标,无论是使用字体图标还是 svg/png 图标,都意味着又得引入别的资源。看样子这个图标不就是个圆圈加根棍子么?自己动手用CSS画。
我大致想了下未来这个插件会变成怎样,一是要把UI做得跟微信差不多,现在的太朴素了点。
然后对同属一个类别下的联系人排序。排序是个有意思的工作,要选那些可以实现快速插入新元素的算法。
不过在此之前,得先写一篇介绍这个插件的文章,宣传一下这个好东西。我现在很想在付出更大努力前,想办法知道值不值得。