跟QQ手机版的表情类似,可以滑动翻页,总共100个表情。上图看看效果吧,这不是APP,你没看错,是Web。是不是感觉比基于jQuery的QQ表情插件看起来高大上些呢。不是说那个不好,主要是那只适用于PC端,在移动端显示效果很差也不好用,所以想模仿QQ的web页面中的表情输入。
一般Web版表情实现方式
查看过jQuery的QQ表情插件应该知道,每个表情有一个图片,通过CSS把每个表情排列好,点击每个表情的时触发对应的事件,将对应编号组成指定格式(如[em_11])输入到文本框,通过将[em_11]转换为html的img标签显示到页面中。
兴趣部落的QQ表情是怎么实现的?
在手机QQ中打开兴趣部落,随便找个话题进去,点击分享,复制链接发到PC,chrome打开对应链接,额,提示要扫码在手机端查看,不急,按下F12打开调试模式,开启手机调试模式(调试窗口左上角手机按钮),随便选择一个Nexus4机型,刷新即可,然后点击评论(需要登录),点击表情按钮,右键审查元素,结构就都显示出来了。
然后发现,每个页面是一张大图,总共5张大图片(其实我最初只是打算来取这几张图片的(>_<),然后就忍不住了)。每次滑动显示下一张图片,每张图片上的每个表情由span标签分割位置(没有使用CSS分割图片,只是记录对应的位置)。通过下面这张图应该能很清楚的看到效果。
这张图怎么来的?且看下面这一句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,如:
<span class="express" index="0" alt="[em_0]"></span>
给class绑定click事件,获取光标之前的文本,检测表情code块,处理添加、删除字符或表情code块。
// 点击表情
$('.express').on('click', function() {
// 获取表情对应code
var imgCode = $(this).attr('alt');
// 获取编号判断是否为删除按钮
var index = $(this).attr('index');
var ta = document.querySelector('textarea');
// 删除操作
if(index == -1){
if ($('#' + curFocus.fid).length) {
var text = $('#' + curFocus.fid).val();
// 获取光标之前的字符串
var changedText = text.substr(0, curFocus.start);
var len = changedText.length;
var reg=/\[em_([0-9]*)\]$/g;
// 删除表情code块或最后一个字符
if(reg.test(changedText)){
changedText=changedText.replace(reg,"");
}else{
changedText=changedText.substring(0,changedText.length-1);
}
var resText = changedText + text.substr(curFocus.end, text.length);
$('#' + curFocus.fid).val(resText);
// 调整光标位置
curFocus.start = curFocus.end = curFocus.end - (len - changedText.length);
}
// 添加操作
}else if ($('#' + curFocus.fid).length) {
var text = $('#' + curFocus.fid).val();
// 添加表情code块到光标位置
var resText = text.substr(0, curFocus.start) + imgCode + text.substr(curFocus.end, text.length);
$('#' + curFocus.fid).val(resText);
curFocus.start = curFocus.end = curFocus.end + imgCode.length;
}
});
2. 分页滑动
通过chrome分析可知兴趣部落采用的是zepto.js做的图片滑动,但是个人觉得太大,于是随便找了个swipe.js(参考http://www.jiawin.com/swipe-mobile-touch-slider),使用相对简单,绑定几个标签和样式即可。
var slider =
Swipe(document.getElementById('slider'), {
continuous: true,
callback: function (pos) {
var i = bullets.length;
while (i--) {
bullets[i].className = ' ';
}
bullets[pos].className = 'js-active';
}
});
var bullets = document.getElementById('position').getElementsByTagName('li');
至于CSS直接从兴趣部落中提取出来的,做了部分修改,兴趣部落的表情太小。
需要查看完整代码可访问QQ表情,需要开启手机调试模式才能查看滑动效果。