这个通讯录现在长这个样子: 幼年期幼年期

以后可能就是这个样子了(我不保证): 完全体完全体

如果我最后放弃改进它,你可以在这里找到源码,然后自己作修改。

这件事情的由来是,公司的设计师在之前的项目里想实现一个跟微信通讯录一样的页面。我没多少把握能在 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做得跟微信差不多,现在的太朴素了点。

然后对同属一个类别下的联系人排序。排序是个有意思的工作,要选那些可以实现快速插入新元素的算法。

不过在此之前,得先写一篇介绍这个插件的文章,宣传一下这个好东西。我现在很想在付出更大努力前,想办法知道值不值得。