打造移动版QQ表情


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

QQ表情
QQ表情


一般Web版表情实现方式

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


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

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


兴趣部落表情
兴趣部落表情

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


JS显示每个HTML标签
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,如:

<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表情,需要开启手机调试模式才能查看滑动效果。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,613评论 25 709
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,296评论 4 61
  • Swift版本点击这里欢迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh阅读 25,651评论 7 249
  • 又一次八点多睡醒,睁开眼又合上,不是不愿意醒来起来,只是真不知道起床要做什么。辞职之后我没有了固定的临时工作,本...
    简伟阅读 282评论 0 0
  • 世界是一面镜子。你认为外界一切都是恶的。外面就会显示与你对立,与你产生对抗关系。 你若认同外界一切都是善的。外面就...
    顿慈悟语阅读 147评论 0 0