我的网站搭建(第49天) 评论框使用emoji表情

  • 发布时间:2017年3月23日 14:40
  • 作者:杨仕航
* 该文是基于Python2.7开发的,最新Python3.x和Django2.x视频教程可以前往 >> Django2.0视频教程

我网站的评论库一直是使用django-comments库。该评论库对垃圾评论和html处理得都挺不错。但问题是只能写入文字,没有提供富文本编辑功能,需要自己开发。为了丰富评论功能,加入表情是一种不错的方案。

当然,你可以用ueditor等富文本编辑器。

但这些都比较复杂、厚重。评论区域我只想需要简单的效果即可,可以写文字和插入表情。

先看看我最终实现的效果,引起大家的好奇心。


1、先合并整理代码

可忽略该步骤(若想了解emoji表情功能如何实现,直接看第2点

因为前面评论和回复开发过程中,把评论框和回复框分开两个。

若这次加入emoji表情功能,需要将评论和回复合并为1个,减少代码冗余度。

相关django-comments评论库的开发可以参考我前面的博文。

我的网站搭建(第5天) Django评论库

我的网站搭建(第6天) 评论Ajax提交

我的网站搭建(第16天) 只允许注册用户评论

我的网站搭建(第17天) 评论库添加回复功能

我的网站搭建(第18天) 评论或回复发送邮件通知

我的网站搭建(第29天) 多线程异步发送邮件

我的网站搭建(第44天) 添加头像字段

我的网站搭建(第45天) 上传头像

我的网站搭建(第46天) 在线头像

我的网站搭建(第47天) 修改评论列表的样式


对比评论框和回复框的代码,发现基本一样。

20170323/20170323135445341.png

只需要控制回复相关3个字段的值即可。而且提交评论和回复的代码前面已经整理过一次。

20170323/20170323135718353.png

代码相似度很高,删掉回复框的代码,修改评论框代码如下:

{% get_comment_form for blog as blog_form %}
<form class="form-horizontal" action="{% comment_form_target %}" method="post" id="comment_form">
    {% csrf_token %}
    {{ blog_form.object_pk }}
    {{ blog_form.content_type }}
    {{ blog_form.timestamp }}
    {{ blog_form.site }}
    {{ blog_form.submit_date }}
    {{ blog_form.security_hash }}
    <input type="hidden" name="next" value="{%url 'detailblog' blog.id%}"/>
    <input id="reply_to" type="hidden" name="reply_to" value="0" />
    <input id="root_id" type="hidden" name="root_id" value="0" />
    <input id="reply_name" type="hidden" name="reply_name" value="">

    <div class="row">
        <div class="col-md-12">
            <textarea class="input-xlarge comment_text" id="id_comment" name="comment" placeholder="为了防止垃圾评论,需要登录,才能评论哦~"></textarea>

            <!--如果你在该字段中输入任何内容,你的评论就会被视为垃圾评论-->
            <input type="text" style="display:none;" id="id_honeypot" name="honeypot">
        </div>
    </div>

    <div class="row">
          <div class="form-actions comment_button">
            <span id='tip_text'></span>
            <input class="btn btn-info" id="submit_btn" type="submit" name="submit" value="提交"/>
            <botton class="btn btn-default" id="reset_btn">清空</botton>
          </div>
    </div>
 </form>


修改评论回复按钮的代码。通过代码控制判断是评论还是回复。

//回复按钮点击事件
function reply_click(obj){
    obj = $(obj);

    //设置回复信息
    $("#reply_to").val(obj.attr("role"));
    $("#root_id").val(obj.attr("root"));
    $("#reply_name").val(obj.attr("base"));
    
    //显示回复的相关内容
    $("#comment_title").text("回复:" + obj.attr("base"));
    $("#reply_text_pre").html($("#comment_"+obj.attr("role")).html()); //显示要回复的评论内容
    $("#reply_text_pre").show();
    $("#reply_cancel").show();

    //评论框获得焦点
    $("#id_comment").focus();
    return false;
}

当然,你还需要一个“取消回复”的按钮,取消回复变成新的评论。

该按钮位置自己随便放。该按钮点击事件代码如下:

//取消回复-按钮
$("#reply_cancel").click(function(){
    //设置相关数据
    $("#reply_to").val('0');
    $("#root_id").val('0');
    $("#reply_name").val("");

    //调整页面显示
    $("#comment_title").text("新的评论");
    $("#reply_text_pre").hide();
    $("#reply_cancel").hide();
});

评论框和回复框的代码合并完成。接下来讲怎么加入emoji表情功能。


2、emoji表情功能实现方式

这个参考过一些文章,查了不少emoji相关的库或前端插件。例如django-emoji、emojione等。

都只是提供一个emoji表情包和emoji字符文本转换图片表情功能。

我还需要一个东西显示emoji表情选择器,方便用户选择并插入表情。而且保存到数据库的时候还是emoji字符文本或者表情的转义文本。


在Github找到一款jQuery插件:emojioneArea

该插件是利用emojione提供的表情库,制作成一个emoji插件。

该插件有两个版本v2和v3,我比较喜欢v2版本的样式。

Github上提供的是v3。而v2需要通过npm安装:

npm install emojionearea@^2.1.3

若觉得安装npm麻烦,可以下载我的demo版本 http://pan.baidu.com/s/1hsr9isO

其中,demo文件夹是官方的demo,包含各种使用方法。

而demo-min文件夹是我的demo文件,只有一个较为精简的例子。


3、在项目中使用emojioneArea

首先引用如下js和css:

<script type="text/javascript" src="js/jquery-1.11.3.min.js"></script>

<!--emojione v2.1.1 使用bootstrap的cdn-->
<link rel="stylesheet" type="text/css" href="http://cdn.bootcss.com/emojione/2.1.1/assets/sprites/emojione.sprites.css">
<script type="text/javascript" src="http://cdn.bootcss.com/emojione/2.1.1/lib/js/emojione.min.js"></script>

<!--emojionearea-->
<link rel="stylesheet" type="text/css" href="css/emojionearea-2.1.3.min.css">
<script type="text/javascript" src="js/emojionearea-2.1.3.min.js"></script>

其中,emojione表情库我使用bootstrap提供的cdn链接。

接着绑定文本框,我原本页面评论框是一个textarea标签,可以直接被emojioneArea绑定。

评论框的id为id_comment,加入如下代码即可:

//使用emojioneArea
$("#id_comment").emojioneArea();

默认使用emojioneArea设置,原本的评论框被隐藏。如下效果:

20170323/20170323142640776.png

由于emojioneArea的编辑框失去焦点,就自动返回文本给原本的评论框。

我现在的页面评论提交代码都是基于原本的评论框。

这么一来,我无须做其他修改,就完成了emoji表情功能


4、评论后显示emoji表情图片

评论后不做任何处理的话,会显示emoji表情的文字字符。

20170323/20170323143049578.jpg

需要用emojione插件的表情字符转图片,代码如下:

//对评论内容的emoji转化
$(".comment_content p, .reply_content p").each(function(){
    $(this).html(emojione.toImage($(this).text()));
});

该代码是找到评论的内容,遍历每一条评论。

获取其文本,通过emojione.toImage方法转换后的结果是html代码。例如:

<img alt="😍" class="emojione">emoji测试

获取到包含emoji的html代码之后,再赋给该元素即可。


但这段代码有跨站脚本攻击的漏洞。例如有人评论内容为:

<script type="text/javascript">alert("hello")</script>

则会被转成html代码执行。修改emoji转化代码如下:

//对评论内容的emoji转化
$(".comment_content p, .reply_content p").each(function(){
    var value = $(this).text();
    var code = $('<div/>').text(value).html(); //html转义
    
    $(this).html(emojione.toImage(code));
});

对内容先转义,再处理emoji则不会出现跨站脚本攻击的漏洞。



当然,还需要加个css样式,修改emoji表情的样式。

.emojione{
    font-size: inherit;
    height: 2ex;
    width: 2.1ex;
    min-height: 20px;
    min-width: 20px;
    display: inline-block;
    margin: -.2ex .15em .2ex;
    line-height: normal;
    vertical-align: middle;
    max-width: 100%;
    top: 0;
}


效果如下:

20170323/20170323143351326.jpg


最后,点击回复按钮需要跳转到emojioneArea编辑框的位置。可以如下代码定位:

$(".emojionearea-editor").focus(); //评论框获得焦点
$("body,html").animate({
        scrollTop: $("#comment_title").offset().top - 90
    }, 100);

comment_title元素是“新的评论”文本。具体元素可以自行设置。

(看完之后,可以评论使用emoji试试 ^_^)

上一篇:机器学习09:逻辑回归详解

下一篇:Django的aggregate究竟是何方妖孽

相关专题: Django评论库开发   

评论列表

jiawei6636

jiawei6636

😀

2020-07-21 20:02 回复

新的评论

清空