参考使用的是微信小程序WeUI组件emoji(最近不知道官方怎么把文档给删除了,在扩展组件中,可以找下)
插入表情方法更新>>参考链接
这个是组件返回的一次文本和图标的参数,怎么存入数据库,并且表情和图片的位置对应上,是个问题!!!!!
存入数据库思路:
具体代码自己写吧,就不贴了,数据库结构贴出来
1、建立两张表
2、表a_biaoqing(当前整个评论):member_id(当前评论的会员ID)
3、表a_biaoqing_wenben(当前评论中的内容):biaoqing_id(当前整个评论的ID)、content(当前评论的文字内容)、type(当前评论的类型)、imageClass(当前评论表情名称)、px_biaoqing(评论文本内容和图标的顺序)、member_id(当前评论的会员ID)
ps:表情和图片的位置对应,是根据查询数据库时,px_biaoqing升序查询就行了。
一、下载文件
官方给的开发示例用开发工具打开看下
可以自己先尝试看下给的示例,最后会给出我写的源码
我修改后的效果
index.wxml
<block wx:for="{{subjects}}" wx:for-item="item" wx:for-index="idx" wx:key="key" wx:if="{{total>0}}">
<view class="record">
<view class="avator"></view>
<view class="comment">
<block wx:for="{{item.list}}" wx:for-item="itemlist" wx:for-index="idxlist" wx:key="keylist">
<block wx:if="{{itemlist.type == 1}}">{{itemlist.content}}</block>
<view wx:if="{{itemlist.type == 2}}"
style="display: inline-block; width: {{lineHeight}}px; height: {{lineHeight}}px">
<view class="{{itemlist.imageClass}}"
style="background-image: url({{emojiSource}});transform-origin: 0 0; transform: scale({{lineHeight / 64}});">
</view>
</view>
</block>
</view>
</view>
</block>
<view class="reply_wrp" style="bottom: {{keyboardHeight}}px">
<view class="reply_tool">
<view class="reply_form_wrp">
<label for="" class="reply_label">
<input class="reply_input" cursor-spacing="8px" confirm-type="send" adjust-position="{{false}}"
value="{{comment}}" cursor="{{cursor}}" focus="{{focus}}" bindblur="onBlur" bindfocus="onFocus"
bindinput="onInput" bindconfirm="showFunction" bindkeyboardheightchange="onkeyboardHeightChange" />
</label>
</view>
<view hover-class="active" class="reply_button replay_emotion_button" bindtap="showEmoji">
<image src="/pages/images/icon_nav_biaoqing.png" mode='aspectFit' class="reply_tool_pic"></image>
</view>
<view hover-class="active" class="reply_button replay_media_button tijiao" bindtap="showFunction">提交</view>
</view>
<view class="reply_panel_wrp" style="height: {{emojiShow ? 300 : 200}}px;" hidden="{{!emojiShow && !functionShow}}">
<view class="reply_panel {{emojiShow ? 'show': ''}}" hidden="{{!emojiShow}}">
<mp-emoji source="{{emojiSource}}" class="mp-emoji" bindinsertemoji="insertEmoji" binddelemoji="deleteEmoji"
bindsend="onsend"></mp-emoji>
</view>
</view>
</view>
index.js
var util = require("../../utils/util.js");
var app = getApp();
Page({
data: {
lineHeight: 24,
functionShow: false,
emojiShow: false,
comment: '',
focus: false,
cursor: 0,
_keyboardShow: false,
emojiSource: 'https://******/images/biaoqingku.png',//表情图标路径,官方给了在最下方
parsedComment: []
},
/**
* 生命周期函数--监听页面加载
*/
onLoad() {
const emojiInstance = this.selectComponent('.mp-emoji')
this.emojiNames = emojiInstance.getEmojiNames()
this.parseEmoji = emojiInstance.parseEmoji
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
var that = this;
var url = app.globalData.swtBase + "****.php?act=main";//这个是查询当前评论的php文件
util.http(that, url, that.mainAddCallback, null, null, '');
},
mainAddCallback: function (that, data) {
var subjects = data.subjects;
var total = data.total;
that.setData({
subjects,
total,
})
},
//键盘高度发生变化的时候触发此事件
onkeyboardHeightChange(e) {
const {
height
} = e.detail
this.setData({
keyboardHeight: height
})
console.log(height)
},
//表情隐藏显示
showEmoji() {
this.setData({
functionShow: false,
emojiShow: this.data._keyboardShow || !this.data.emojiShow,
keyboardHeight: 0
})
},
//获取焦点时触发光标在最后,隐藏表情栏
onFocus() {
this.setData({
cursor: this.data.cursor,
functionShow: false,
emojiShow: this.data._keyboardShow,
})
},
//输入框失去焦点时触发,隐藏键盘,隐藏表情框
onBlur(e) {
this.setData({
_keyboardShow: false,
cursor: e.detail.cursor || 0,
keyboardHeight: 0,
})
},
//当键盘输入时,指定删除时
onInput(e) {
var keyCode = e.detail.keyCode;
if (keyCode == 8) { //表示删除。本来想点击键盘自带的删除时,文字和表情能够区分删除,没弄明白。
// this.triggerEvent('delemoji');
}
var value = e.detail.value;
//非自带表情通过encodeURIComponent() 函数把字符串作为 URI 组件进行编码
var regex = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig
var value = value.replace(regex, function (res) {
return encodeURIComponent(res)
})
console.log(value)
//this.data.comment = util.filterEmoji(value); //非自带表情过滤
this.data.comment = value; //不进行过滤2.0
},
//添加表情
insertEmoji(evt) {
const emotionName = evt.detail.emotionName
const {
cursor,
comment
} = this.data
const newComment =
comment.slice(0, cursor) + emotionName + comment.slice(cursor)
this.setData({
comment: newComment,
cursor: cursor + emotionName.length
})
},
//删除表情,区分文字和表情符号
deleteEmoji: function () {
const pos = this.data.cursor;
const comment = this.data.comment;
let result = '',
cursor = 0
let emojiLen = 6
let startPos = pos - emojiLen
if (startPos < 0) {
startPos = 0
emojiLen = pos
}
const str = comment.slice(startPos, pos)
const matchs = str.match(/\[([\u4e00-\u9fa5\w]+)\]$/g)
// 删除表情
if (matchs) {
const rawName = matchs[0]
const left = emojiLen - rawName.length
if (this.emojiNames.indexOf(rawName) >= 0) {
const replace = str.replace(rawName, '')
result = comment.slice(0, startPos) + replace + comment.slice(pos)
cursor = startPos + left
}
// 删除字符
} else {
let endPos = pos - 1
if (endPos < 0) endPos = 0
const prefix = comment.slice(0, endPos)
const suffix = comment.slice(pos)
result = prefix + suffix
cursor = endPos
}
this.setData({
comment: result,
cursor: cursor
})
},
//点击提交时触发,和点击键盘完成时触发
showFunction() {
const comment = this.data.comment;
const parsedComment = this.parseEmoji(this.data.comment);
this.setData({
parsedComment,
})
if (!comment) {
wx.showModal({
title: '提示',
content: '请输入内容!',
showCancel: false
})
return;
}
this.onSubmit(); //提交信息
},
//提交
onSubmit() {
var that = this;
var parsedComment = that.data.parsedComment;
console.log(parsedComment)
var htmlDatas = {
htmlDatas: JSON.stringify(parsedComment)
};
wx.showLoading({
title: '正在提交..',
mask: true
})
var url = app.globalData.swtBase + "****.php?act=add";//这个是提交当前评论的php文件
util.http(that, url, that.addrAddCallback, null, htmlDatas, '', 'POST');
},
//提交反馈
addrAddCallback: function (that, data) {
wx.hideLoading();
wx.showModal({
title: '提示',
content: '提交成功',
showCancel: false,
})
//清除输入框,隐藏表情框
that.setData({
functionShow: false,
emojiShow: this.data._keyboardShow,
comment: '',
parsedComment: [],
})
//重新加载本页面
that.onShow();
}
})
index.json
{
"usingComponents": {
"mp-emoji": "../../components/emoji/index"
}
}
2021-05-31更新
支持发送键盘自带表情!!!
上一个版本是把手机自带的表情库屏蔽了,显示*号。
这个版本可以发送手机自带表情,和已有库的表情
这里可以发现微笑和寒冷完全是两个不同库的表情
原理:
参考链接
//将emoji表情进行转义再发送至后台
var nikeName= '小罗老师%F0%9F%98%82'
let regex = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig
let nickNameNew = nickName.replace(regex, function (res) {
return encodeURIComponent(res)
})
//后台返回'小罗老师%F0%9F%98%82'时,使用decodeURIComponent()进行解析
let data = '小罗老师%F0%9F%98%82'
console.log(decodeURIComponent(data ))
php文件处理文本内容时,需要进行一个urldecode解码的操作
2021-07-17更新
支持发送语音
点击文字播放就可以播放语音了,至于样式嘛,没时间了,关键问题好了还怕样式嘛?。
如果需要把语音上传到服务器,还需要自己在写一个上传文件。参考:微信小程序PHP之图片多图,单图实时上传。外加微信图片安全检测
源码以更新