之前折腾过一次评论表情,源码来自网络,可以说是非常强大,表情图标可以说是和手机系统一样充裕,但对于网站评论用就显得太过于杂乱了。
评论发表后表情不显示
虽然所有的图标都分好类了,但不是12类别中的每个图标都会用到,增加用户发表评论的时间,对于网站的体验感来说是非常差的。
这两天本来想着精简一下,但修改源码时发现里面代码比较复杂,有些图标使用的还是背景定位来实现的,查找位置非常麻烦,有些代码根据正常删减竟然出现整个都不显示了,最后不得不放弃,也因此想着更换另外一种表情。
于是便找到了今天的主角OwO表情,其实上次也想着折腾过,但当时只想着搬运(复制/粘贴),没有仔细研究,以致于后面没有成功直接就放弃了。
OwO是一款可爱且实用的js表情符号插件。OwO表情符号插件可以在文本域或输入框中输入表情符号,它支持颜文字、Emoji、图片等,支持移动端,表情数据从一个可以自定义的json接口读取。
配置方法
下载OwO表情插件文件,并把OwO.json、OwO.min.css和OwO.min.js放入自己网站适当的位置。
下载地址见文末。
在页面中引入OwO.min.css和OwO.min.js文件。
<link rel="stylesheet" href="OwO.min.css">
<script src="OwO.min.js"></script>
打开主题文件夹下面的comment.php
文件,找到textarea
并在class项加上OwO-textarea
,同时加上表情符号容器。最后代码类似下面:
<!-- 目标元素 -->
<textarea class="OwO-textarea"></textarea>
<!-- 表情符号容器 -->
<div class="OwO"></div>
初始化插件,在底部加上下面的代码。
var OwO_demo = new OwO({
logo: 'OωO表情',
container: document.getElementsByClassName('OwO')[0],
target: document.getElementsByClassName('OwO-textarea')[0],
api: './OwO.json',
position: 'down',
width: '100%',
maxHeight: '250px'
});
参数说明如下:
- logo:按钮上的文本,默认为”OωO表情”
- container:OwO表情符号的容器
- target:OwO表情符号的目标textarea或input元素(注意与textarea的class名称一致)
- api:OwO表情符号使用的json数据(注意与自己的文件路径一致)
- position:OwO表情符号body的位置
- width:OwO表情符号body的宽度
注意事项
图片表情:位置及格式必须与上面js文件中的一致
至此表情基本配置完成并可以正常使用了,但发现发表文字表情都会在评论框上显示,而发表图片表情时就会显示图片的html代码:
<img src="haha.gif">
这样在评论框不仅太占地方,而且也不美观。研究OwO.json时会发现显示的内容就是json文件中的icon数据。
"文字": {
"type": "emoticon",
"container": [
{
"icon": "^_^",
"text": "xwz"
}
]
},
"Emoji": {
"type": "emoji",
"container": [
{
"icon": "😂",
"text": "haha"
}
]
},
"图片表情": {
"type": "image",
"container": [
{
"icon": "<img src=\"//wanghao.me/haha.gif\">",
"text": "haha"
}
]
}
扩展应用
在网友@CFanLost的Typecho程序网站上发表评论表情时只显示表情名称短代码,于是想着在Wordpress中应该也是可以这样操作的,因为json文件中的emoticon和emoji类型表情所见即所得,只有图片表情需要修改,所以只需要在js中加一下if判断就可以了,类似结构如下:
if type = image
‘<img src=”icon.gif”>’
else
‘icon’
修改完成后完整的OwO.min.js代码如下:
"use strict";
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
(function () {
var OwO = function () {
function OwO(option) {
var _this = this;
_classCallCheck(this, OwO);
var defaultOption = {
logo: 'OwO表情',
container: document.getElementsByClassName('OwO')[0],
target: document.getElementsByTagName('textarea')[0],
position: 'down',
width: '100%',
maxHeight: '235px',
api: 'https://api.anotherhome.net/OwO/OwO.json'
};
for (var defaultKey in defaultOption) {
if (defaultOption.hasOwnProperty(defaultKey) && !option.hasOwnProperty(defaultKey)) {
option[defaultKey] = defaultOption[defaultKey];
}
}
this.container = option.container;
this.target = option.target;
if (option.position === 'up') {
this.container.classList.add('OwO-up');
}
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
_this.odata = JSON.parse(xhr.responseText);
_this.init(option);
} else {
console.log('OwO data request was unsuccessful: ' + xhr.status);
}
}
};
xhr.open('get', option.api, true);
xhr.send(null);
}
_createClass(OwO, [{
key: 'init',
value: function init(option) {
var _this2 = this;
this.area = option.target;
this.packages = Object.keys(this.odata); // fill in HTML
var html = '\n <div class="OwO-logo">' + option.logo + '</div>\n <div class="OwO-body" style="width: ' + option.width + '">';
for (var i = 0; i < this.packages.length; i++) {
html += '\n <ul class="OwO-items OwO-' + this.odata[this.packages[i]].name + ' OwO-items-' + this.odata[this.packages[i]].type + '" style="max-height: ' + (parseInt(option.maxHeight) - 53 + 'px') + ';">';
var opackage = this.odata[this.packages[i]].container;
for (var _i = 0; _i < opackage.length; _i++) {
if (this.odata[this.packages[i]].type === 'image') {
html += '\n <li class="OwO-item" title="' + opackage[_i].text + '" data-input="' + this.odata[this.packages[i]].name + ":" + opackage[_i].icon + '">' + '<img data-original="' + 'https://www.wanghao.me/wp-content/themes/love/assets/plugins/0w0/images/' + opackage[_i].icon + '.gif" src="" icon="' + opackage[_i].text + '"></li>';
} else {
html += '\n <li class="OwO-item" title="' + opackage[_i].text + '">' + opackage[_i].icon + '</li>';
}
}
html += '\n </ul>';
}
html += '\n <div class="OwO-bar">\n <ul class="OwO-packages">';
for (var _i2 = 0; _i2 < this.packages.length; _i2++) {
html += '\n <li><span>' + this.packages[_i2] + '</span></li>';
}
html += '\n </ul>\n </div>\n </div>\n ';
this.container.innerHTML = html; // bind event
this.logo = this.container.getElementsByClassName('OwO-logo')[0];
this.logo.addEventListener('click', function () {
_this2.toggle();
});
this.container.getElementsByClassName('OwO-body')[0].addEventListener('click', function (e) {
var target = null;
var type = 0;
if (e.target.classList.contains('OwO-item')) {
target = e.target; //console.log("文字表情");
} else if (e.target.parentNode.classList.contains('OwO-item')) {
target = e.target.parentNode; //target = e.target;
//console.log("图片表情");
}
if (target) {
var startPos = _this2.area.selectionStart;
var endPos = _this2.area.selectionEnd;
var areaValue = _this2.area.value;
var insertContent;
if (target.dataset.hasOwnProperty("input")) {
insertContent = " ::" + target.dataset.input + ":: ";
} else {
insertContent = target.innerHTML;
}
_this2.area.value = areaValue.slice(0, startPos) + insertContent + areaValue.slice(endPos); //console.log("areaValue" + areaValue); 编辑器的内容
//console.log("target" + insertContent); //插入的内容
_this2.area.selectionStart = startPos + insertContent.length;
_this2.area.selectionEnd = startPos + insertContent.length;
_this2.area.focus(); //定位到光标位置
_this2.toggle();
}
});
this.packagesEle = this.container.getElementsByClassName('OwO-packages')[0];
var _loop = function _loop(_i3) {
(function (index) {
_this2.packagesEle.children[_i3].addEventListener('click', function () {
_this2.tab(index);
});
})(_i3);
};
for (var _i3 = 0; _i3 < this.packagesEle.children.length; _i3++) {
_loop(_i3);
}
this.tab(0);
}
}, {
key: 'toggle',
value: function toggle() {
// console.log("toggle");
if (this.container.classList.contains('OwO-open')) {
this.container.classList.remove('OwO-open');
} else {
this.container.classList.add('OwO-open');
}
var secret = document.getElementById("secret_comment");
if (secret) {
if (secret.offsetParent === null) {
secret.style.display = "block";
} else {
secret.style.display = "none";
}
} //懒加载该区域类的图片
try {
$("img").lazyload({
effect: "fadeIn"
});
} catch (e) {
// console.log(this.container.classList);
if (this.container.classList.contains("OwO-open")) {
var a = this.container.querySelectorAll(".OwO-items.OwO-items-show>li img");
[].forEach.call(a, function (a) {
var b = a.dataset.original;
b && (a.src = b, a.removeAttribute("data-src"));
});
}
}
}
}, {
key: 'tab',
value: function tab(index) {
// console.log("tab");
//切换选项卡对于的ul区域显示
var itemsShow = this.container.getElementsByClassName('OwO-items-show')[0];
if (itemsShow) {
itemsShow.classList.remove('OwO-items-show');
}
this.container.getElementsByClassName('OwO-items')[index].classList.add('OwO-items-show'); //切换选项卡的选中状态
var packageActive = this.container.getElementsByClassName('OwO-package-active')[0];
if (packageActive) {
packageActive.classList.remove('OwO-package-active');
}
this.packagesEle.getElementsByTagName('li')[index].classList.add('OwO-package-active'); //懒加载该区域类的图片
try {
$("img").lazyload({
effect: "fadeIn"
});
} catch (e) {
if (this.container.classList.contains("OwO-open")) {
var a = this.container.querySelectorAll(".OwO-items.OwO-items-show>li img");
[].forEach.call(a, function (a) {
var b = a.dataset.original;
b && (a.src = b, a.removeAttribute("data-original"));
});
}
}
}
}]);
return OwO;
}();
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = OwO;
} else {
window.OwO = OwO;
}
})();
代码比较多,大家仔细研究,并根据自己的主题修改表情图片位置及格式。
然后json文件中图片表情更改如下:
"图片表情": {
"type": "image",
"container": [
{
"icon": "haha",
"text": "haha"
}
]
}
现在发表评论表情时评论框会显示::haha::
,发表成功也是这样,而不是具体的haha表情图片,这是因为我们还需要对表情短代码与图片进行转义,在functions.php
文件中加入下列代码:
add_filter('smilies_src','custom_smilies_src',1,10);
function custom_smilies_src ($img_src, $img, $siteurl){
return get_bloginfo('template_directory').'/assets/images/smiles/'.$img;
//注意表情图片路径
}
function disable_emojis_tinymce( $plugins ) {
return array_diff( $plugins, array( 'wpemoji' ) );
}
function smilies_reset() {
global $wpsmiliestrans, $wp_smiliessearch;
if ( !get_option( 'use_smilies' ))
return;
$wpsmiliestrans = array(
'::haha::' => 'haha.gif',
);
}
smilies_reset();
现在试试是不是可以愉快的发表表情了,样式及代码路径等根据自己的主题来适配。
上面是关于评论加入表情按钮和发表评论添加表情的方法,当然还可以在发表文章时插入表情符号。
文章中插入表情符号
同样打开functions.php
文件,加入下列代码即可。注意表情路径改为你自己的。
function fa_get_wpsmiliestrans() {
global $wpsmiliestrans;
$wpsmilies = array_unique($wpsmiliestrans);
$output = '';
foreach ($wpsmilies as $alt => $src_path) {
$output.= '<a class="add-smily" data-smilies="' . $alt . '"><img class="wp-smiley" style="height:24px;width:24px;" src="' . get_bloginfo('template_directory') . '/assets/plugins/0w0/images/' . rtrim($src_path, "gif") . 'gif" /></a>';
}
return $output;
}
add_action('media_buttons_context', 'fa_smilies_custom_button');
function fa_smilies_custom_button($context) {
$context = '';
$context.= '<style>.smilies-wrap{background:#fff;border: 1px solid #ccc;box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.24);padding: 10px;position: absolute;top: 60px;width: 375px;display:none}.smilies-wrap img{height:24px;width:24px;cursor:pointer;margin-bottom:5px} .is-active.smilies-wrap{display:block}</style> <a id="insert-media-button" style="position:relative; line-height:36px" class="button insert-smilies add_smilies" title="添加表情" data-editor="content" href="javascript:;">^_^ 添加表情</a><div class="smilies-wrap">' . fa_get_wpsmiliestrans() . '</div><script>jQuery(document).ready(function(){jQuery(document).on("click", ".insert-smilies",function() { if(jQuery(".smilies-wrap").hasClass("is-active")){jQuery(".smilies-wrap").removeClass("is-active");}else{jQuery(".smilies-wrap").addClass("is-active");}});jQuery(document).on("click", ".add-smily",function() { send_to_editor(" " + jQuery(this).data("smilies") + " ");jQuery(".smilies-wrap").removeClass("is-active");return false;});});</script>';
return $context;
}
参考资料
OwO表情插件:https://github.com/DIYgod/OwO
Emojipedia: https://emojipedia.org
Handsome-static:https://github.com/ihewro/handsome-static
新浪微博表情api: https://api.weibo.com/2/emotions.json?source=1362404091
这种表情图标样式及功能其实一直是我想要的,只是一直以来因为自己的能力问题没有实现,今天终于解决了!在此感谢插件作者(江湖人称狗哥)和CFanLost及其Typecho网站的主题作者。
现在的表情图标不是很多,后续慢慢补充,如果大家想要补充什么图标欢迎在下面评论告诉我。