富文本编辑器wangEditor多语言、工具栏体验改造
富文本编辑器wangEditor多语言、工具栏体验改造
支持多语言
首页wangEditro本身是支持使用多语言的,通过源码可以看到里面有个replaceLang
方法,虽然这种写法有点非主流,但是是有效的,里面部分地方在支持多语言方面有些遗漏。
以“加粗”功能为例
// 构造函数
function Bold(editor) {
this.editor = editor;
this.title = '加粗';
const title = replaceLang(editor, this.title);
this.$elem = $(
'<div class="w-e-menu">\n <i class="w-e-icon-bold" title="' + title + '"></i>\n </div>',
);
this.type = 'click';
// 当前是否 active 状态
this._active = false;
}
看下replaceLang
方法干了什么
/*
替换多语言
*/
var replaceLang = function(editor, str) {
var langArgs = editor.config.langArgs || [];
var result = str;
langArgs.forEach(function(item) {
var reg = item.reg;
var val = item.val;
if (reg.test(result)) {
result = result.replace(reg, function() {
return val;
});
}
});
return result;
};
通过传入参数langArgs
数组,然后进行遍历,这个方法简单粗暴,缺点也很明显,每次调用replaceLang
就会把整个数组遍历一遍。。。
wangEditor的源码里面是直接写的中文,对于加粗的话,你可能需要这样才行:
[{
reg: '加粗',
value: 'Bold',
}]
在现在很多公司的发布工具会扫描中文的,那样源码的里面的“加粗”肯定是中招了。
工具栏体验改造
wangEditor默认是支持加粗后对应的图标B变成蓝色高亮的,类似的还有斜体、下划线、删除线,但是字体颜色是没有类似的功能(可能是作者偷懒了吧),这样会导致体验不佳。 上图中最后的暗红色铅笔图标就是显示的字体颜色,是我后期自行实现,我们现在看看具体怎么实现的吧。
依葫芦画瓢,我们看下“加粗”的这个功能怎么实现的
// 原型
Bold.prototype = {
constructor: Bold,
// 点击事件
onClick: function onClick(e) {
// 点击菜单将触发这里
var editor = this.editor;
var isSeleEmpty = editor.selection.isSelectionEmpty();
if (isSeleEmpty) {
// 选区是空的,插入并选中一个“空白”
editor.selection.createEmptyRange();
}
// 执行 bold 命令
editor.cmd.do('bold');
if (isSeleEmpty) {
// 需要将选取折叠起来
editor.selection.collapseRange();
editor.selection.restoreSelection();
}
},
// 试图改变 active 状态
tryChangeActive: function tryChangeActive(e) {
var editor = this.editor;
var $elem = this.$elem;
if (editor.cmd.queryCommandState('bold')) {
this._active = true;
$elem.addClass('w-e-active');
} else {
this._active = false;
$elem.removeClass('w-e-active');
}
},
};
我们可以看到里面有queryCommandState('bold')
,对就是document.queryCommandState
这个API,我们可以查询到当前光标处是否实行了加粗,我们可以在MDN上看看它支持哪些参数。
tryChangeActive
是什么时候调用的呢?
// 尝试修改菜单状态
changeActive: function changeActive() {
var menus = this.menus;
objForEach(menus, function(key, menu) {
if (menu.tryChangeActive) {
setTimeout(function() {
menu.tryChangeActive();
}, 100);
}
});
},
调用changeActive
是会调用菜单每一项的tryChangeActive
方法。
那我们是什么时候调用changeActive
呢?
有两个地方
1.保存选区
// 实时保存选取
_saveRangeRealTime: function _saveRangeRealTime() {
var editor = this.editor;
var $textElem = editor.$textElem;
// 保存当前的选区
function saveRange(e) {
// 随时保存选区
editor.selection.saveRange();
// 更新按钮 ative 状态
editor.menus.changeActive();
}
// 按键后保存
$textElem.on('keyup', saveRange);
$textElem.on('mousedown', function(e) {
// mousedown 状态下,鼠标滑动到编辑区域外面,也需要保存选区
$textElem.on('mouseleave', saveRange);
});
$textElem.on('mouseup', function(e) {
saveRange();
// 在编辑器区域之内完成点击,取消鼠标滑动到编辑区外面的事件
$textElem.off('mouseleave', saveRange);
});
},
2.调用do方法
// 修改原型
Command.prototype = {
constructor: Command,
// 执行命令
do: function _do(name, value) {
var editor = this.editor;
// 使用 styleWithCSS
if (!editor._useStyleWithCSS) {
document.execCommand('styleWithCSS', null, true);
editor._useStyleWithCSS = true;
}
// 如果无选区,忽略
if (!editor.selection.getRange()) {
return;
}
// 恢复选取
editor.selection.restoreSelection();
// 执行
var _name = '_' + name;
if (this[_name]) {
// 有自定义事件
this[_name](value);
} else {
// 默认 command
this._execCommand(name, value);
}
// 修改菜单状态
editor.menus.changeActive();
// 最后,恢复选取保证光标在原来的位置闪烁
editor.selection.saveRange();
editor.selection.restoreSelection();
// 触发 onchange
editor.change && editor.change();
},
...
}
我们改造实现下前面提到的字体颜色。
function ForeColor(editor) {
this.editor = editor;
this._action = 'foreColor';
...
}
ForeColor.prototype = {
constructor: ForeColor,
...
tryChangeActive: function tryChangeActive(e) {
checkIconActive.call(this, 'ForeColor');
}
...
}
function checkIconActive(type) {
var editor = this.editor;
var $elem = this.$elem;
let color = editor.cmd.queryCommandValue(this._action);
color = colorRGBtoHex(color);
color = color === '#ffffff' ? '#eeece0' : color; // 纯白色不好识别,改用#eeece0
$elem.children()[0].style.color = color;
}
看了上面的写法,有经验的朋友应该会想到背景色也可以这样实现,修改this._action
的值即可。
这样我们就实现此类工具栏的改造,我们可以按照类似的方法实现另外两类工具栏图标的改造。
一类是设置标题这种,只有有对应“样式”就蓝色高亮,在hover时下拉列表显示匹配到的样式。
另一类就是对齐方式、列表方式这种,相比上一种多一个同步修改工具栏对应icon的功能。
这两类就直接上代码了。
function checkActive(type) {
const $elem = this.$elem;
const editor = this.editor;
const values = this._actions.map(item => editor.cmd.queryCommandState(item) && item);
const [activeValue] = values.filter(item => item);
const deletedValues = this._actions.filter(item => item !== activeValue);
const elemClassList = $elem.children()[0].classList;
deletedValues.forEach(item => {
const inActiveClassName = this._iconMap[item];
elemClassList.remove(inActiveClassName);
$elem.find('.' + inActiveClassName).removeClass('w-e-active');
});
const activeClassName = this._iconMap[activeValue];
if (activeClassName) {
this._active = true;
elemClassList.add('w-e-active');
elemClassList.add(activeClassName);
$elem.find('.' + activeClassName).addClass('w-e-active');
} else {
this._active = false;
const defaultClassName = this._iconMap.default;
elemClassList.remove('w-e-active');
elemClassList.add(defaultClassName);
}
}
function checkListActive(type, getValue) {
const $elem = this.$elem;
const editor = this.editor;
const value = typeof getValue === 'function' ? getValue() : editor.cmd.queryCommandValue(this._action);
const children = $elem.find('ul.w-e-list').children();
if (!children) {
return;
}
children.removeClass('w-e-active');
// 先清除
const elemClassList = $elem.children()[0].classList;
elemClassList.remove('w-e-active');
const activeIndex = this._iconMap[value];
if (activeIndex !== void 0) { // 能枚举到的就设为active
// 后设置
this._active = true;
elemClassList.add('w-e-active');
children[activeIndex] && children[activeIndex].classList.add('w-e-active');
} else {
this._active = false;
elemClassList.remove('w-e-active');
}
}
- 分类:
- Web前端
相关文章
富文本编辑器wangEditor迁移CKEditor前后效果对比
一、背景 富文本编辑器wangEditor的工具栏如图所示 富文本编辑器CKEditor4工具栏如图所示 二、wangEditor编辑器存在问题 1. 字号和字体设置 阅读更多…
wangEditor输入中文后直接粘贴bug来了解compositionstart
昨天有人反馈邮件编辑过程中的一个报障,具体内容就是在编辑器中输入中文然后直接粘贴先前复制好的信息,然后出现了bug,比如之前复制了订单号“1234”,再输入“您的订单号”后直接粘贴,编辑器内显示的结 阅读更多…
在iframe中使用富文本编辑器wangEditor
自己做的邮件项目里面需要使用到富文本编辑器,邮件内容说白了就是HTML代码。前任使用的是wangEditor,部分定制化需求就是直接改的源码。 最近发现有的用户的邮件内容加进去的很多css信息, 阅读更多…
2021年的一点工作总结(二)富文本编辑器
邮件项目的核心功能就是编辑邮件了,所以文本的编辑特别容易被用户吐槽了。用户报障的时候一个万能的吐槽点“没有xxx功能,不支持xxx,没有Outlook好用”。 其实作为一个web产品,如果需要更加公 阅读更多…
wangEditor富文本编辑器改造记录之一——了解wangEditor结构
最近鉴于项目要求,需要对自己使用的富文本编辑器进行改造。 我们首先简单了解下wangEditor的源码结构 第一步:polyfill 当然现在这些基本都用不上了,现代点的浏览器都支持这些 阅读更多…