[关闭]
@skyway 2015-05-12T16:43:30.000000Z 字数 2728 阅读 948

打造移动版QQ表情

QQ表情 JS


跟QQ手机版的表情类似,可以滑动翻页,总共100个表情。上图看看效果吧,这不是APP,你没看错,是Web。是不是感觉比基于jQuery的QQ表情插件看起来高大上些呢。不是说那个不好,主要是那只适用于PC端,在移动端显示效果很差也不好用,所以想模仿QQ的web页面中的表情输入。
QQ表情


一般Web版表情实现方式

查看过jQuery的QQ表情插件应该知道,每个表情有一个图片,通过CSS把每个表情排列好,点击每个表情的时触发对应的事件,将对应编号组成指定格式(如[em_11])输入到文本框,通过将[em_11]转换为html的img标签显示到页面中。


兴趣部落的QQ表情是怎么实现的?

在手机QQ中打开兴趣部落,随便找个话题进去,点击分享,复制链接发到PC,chrome打开对应链接,额,提示要扫码在手机端查看,不急,按下F12打开调试模式,开启手机调试模式(调试窗口左上角手机按钮),随便选择一个Nexus4机型,刷新即可,然后点击评论(需要登录),点击表情按钮,右键审查元素,结构就都显示出来了。
兴趣部落表情

然后发现,每个页面是一张大图,总共5张大图片(其实我最初只是打算来取这几张图片的(>_<),然后就忍不住了)。每次滑动显示下一张图片,每张图片上的每个表情由span标签分割位置(没有使用CSS分割图片,只是记录对应的位置)。通过下面这张图应该能很清楚的看到效果。
JS显示每个HTML标签

这张图怎么来的?且看下面这一句JS(哈哈,装逼的时候到了,这句话总算派上用场了)
```
[].forEach.call($$("*"),function(a){
  a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)
})
```
当然,这不是我写的,这一句话很值得慢慢品味,附上原文链接[Learning much javascript from one line of code](http://arqex.com/939/learning-much-javascript-one-line-code?utm_source=ourjs.com)

继续,然后每个表情也有一张单独的图片,并且比大图中的更清晰。发表之后,根据img标签去访问对应的图片即可。

为什么用这种方式?
* 5张大图100个表情总共100K左右,如果采用滑动时加载的话,初次载入只需要20K,而发送时才会去访问对应表情的单张图片。而如果是之前jQuery插件方式,75个表情总共221K需要一次性载入,或者分5次载入,也需要每次50K左右。
* 其次整张图片的形式可以做到根据屏幕宽度对应缩放,而单个的调整起来麻烦且不清晰。


实现过程

1. 点击表情

通过上面的分析可以知道,每个span标签包含着对应表情,通过给每个标签绑定相同的class,不同的alt,如:

  1. <span class="express" index="0" alt="[em_0]"></span>

给class绑定click事件,获取光标之前的文本,检测表情code块,处理添加、删除字符或表情code块。

  1. // 点击表情
  2. $('.express').on('click', function() {
  3. // 获取表情对应code
  4. var imgCode = $(this).attr('alt');
  5. // 获取编号判断是否为删除按钮
  6. var index = $(this).attr('index');
  7. var ta = document.querySelector('textarea');
  8. // 删除操作
  9. if(index == -1){
  10. if ($('#' + curFocus.fid).length) {
  11. var text = $('#' + curFocus.fid).val();
  12. // 获取光标之前的字符串
  13. var changedText = text.substr(0, curFocus.start);
  14. var len = changedText.length;
  15. var reg=/\[em_([0-9]*)\]$/g;
  16. // 删除表情code块或最后一个字符
  17. if(reg.test(changedText)){
  18. changedText=changedText.replace(reg,"");
  19. }else{
  20. changedText=changedText.substring(0,changedText.length-1);
  21. }
  22. var resText = changedText + text.substr(curFocus.end, text.length);
  23. $('#' + curFocus.fid).val(resText);
  24. // 调整光标位置
  25. curFocus.start = curFocus.end = curFocus.end - (len - changedText.length);
  26. }
  27. // 添加操作
  28. }else if ($('#' + curFocus.fid).length) {
  29. var text = $('#' + curFocus.fid).val();
  30. // 添加表情code块到光标位置
  31. var resText = text.substr(0, curFocus.start) + imgCode + text.substr(curFocus.end, text.length);
  32. $('#' + curFocus.fid).val(resText);
  33. curFocus.start = curFocus.end = curFocus.end + imgCode.length;
  34. }
  35. });

2. 分页滑动

通过chrome分析可知兴趣部落采用的是zepto.js做的图片滑动,但是个人觉得太大,于是随便找了个swipe.js(参考http://www.jiawin.com/swipe-mobile-touch-slider),使用相对简单,绑定几个标签和样式即可。

  1. var slider =
  2. Swipe(document.getElementById('slider'), {
  3. continuous: true,
  4. callback: function (pos) {
  5. var i = bullets.length;
  6. while (i--) {
  7. bullets[i].className = ' ';
  8. }
  9. bullets[pos].className = 'js-active';
  10. }
  11. });
  12. var bullets = document.getElementById('position').getElementsByTagName('li');

至于CSS直接从兴趣部落中提取出来的,做了部分修改,兴趣部落的表情太小。
需要查看完整代码可访问http://runjs.cn/detail/pdstukmr,需要开启手机调试模式才能查看滑动效果。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注