最近项目中需要开发一个问卷调查的模块,于是参考腾讯问卷使用ckeditor,该编辑器最大的优点就是可以使用行内模式(inline)。
根据官网的指引,将完整的项目包下到本地后,就可以在项目中使用了。
在项目中引入ckeditor.js
即可立即使用。当然,需要在被替换的div上加上contenteditable="true"
属性,该属性可以让当前dom元素可编辑。然后刷新页面,你就会发现div上方会出现toolbar工具栏。
此时会发现默认展示所有的工具,但这并不是我们想要的,因为实在太多了。这就需要我们定制config.js
文件。在下载下来的插件目录中有一个index.html
文件,进入根据页面提示就可以定制需要的配置文件。我的配置文件是这样的:
//定制工具栏,包括加粗、斜体、下划线、中划线、字体颜色、背景颜色、图片上传和超链接。
CKEDITOR.editorConfig = function( config ) {
config.toolbarGroups = [
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] },
{ name: 'forms', groups: [ 'forms' ] },
'/',
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi', 'paragraph' ] },
{ name: 'colors', groups: [ 'colors' ] },
{ name: 'insert', groups: [ 'insert' ] },
{ name: 'links', groups: [ 'links' ] },
'/',
{ name: 'styles', groups: [ 'styles' ] },
{ name: 'tools', groups: [ 'tools' ] },
{ name: 'others', groups: [ 'others' ] },
{ name: 'about', groups: [ 'about' ] }
];
config.removeButtons = 'Source,Save,NewPage,Preview,Print,Templates,Cut,Paste,Copy,PasteText,PasteFromWord,Undo,Redo,Find,Replace,SelectAll,Scayt,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,Subscript,Superscript,CopyFormatting,RemoveFormat,NumberedList,BulletedList,Outdent,Indent,CreateDiv,Blockquote,JustifyLeft,JustifyCenter,JustifyRight,JustifyBlock,BidiLtr,BidiRtl,Language,Unlink,Anchor,Flash,Table,HorizontalRule,Smiley,PageBreak,SpecialChar,Iframe,Styles,Format,Font,FontSize,Maximize,ShowBlocks,About';
//超链接高级设置选项不显示
config.linkShowAdvancedTab = false;
//超链接目标选项不显示
config.linkShowTargetTab = false;
//鼠标悬停不展示title
config.title = false;
//图片上传到服务器的地址
config.filebrowserImageUploadUrl = '/ck/upload';
//图片上传方式
config.filebrowserUploadMethod = 'form';
//清空图片预览文本
config.image_previewText=' ';
};
将配置放入到config.js
后,刷新页面会发现出现定制后的工具栏。
如果项目不是SPA,或者页面中只需要一个行内富文本编辑器,到这里应该就可以了,但是公司项目采用的是VUE,这就涉及到一个加载顺序和渲染的问题了。
我这里的做法是每次新创建编辑器DOM的时候,就先把所有的编辑器实例销毁掉然后重新初始化。代码如下:
//全部重新初始化
setTimeout(()=>{
let node = Object.keys(CKEDITOR.instances);
for (let i = 0; i < node.length; i++) {
let item = CKEDITOR.instances[node[i]];
if (item) {
//销毁所有实例
item.destroy(true);
}
}
//重新初始化
CKEDITOR.inlineAll();
},100);
这样,页面就不报错了。
最难搞的要数图片上传。上面config的配置大部分都是来配置上传图片的内容。而且需要后台兄弟的配合,返回特定的内容。
当配置了图片上传到服务器的地址后,图片上传的dialog会出现上传的tab页,选好图片上传到指定服务器后,需要让服务器返回如下脚本:
// 图片地址为腾讯问卷返回的地址
<script>window.parent.CKEDITOR.tools.callFunction(1, 'https://cdn.ur.qq.com/uploadImages//2018-04-19/201804191805395ad869f38787d.PNG', '');</script>
//上传图片时,插件会自动在上传请求后拼接如下内容
CKEditor=editor&CKEditorFuncNum=1&langCode=zh-cn
//而返回脚本内方法的第一个参数就是拼接内容CKEditorFuncNum的值。此处为1
当成功返回后,dialog就会出现图片的绝对路径和预览。同时也会出现默认给图片设置宽高的style值。可是这并不是我们想要的,如果需要去除默认设置宽高,需要更改ckeditor image插件的配置文件了。下面方法适用于最新版本4.9.1。以前版本不保证可用。
打开目录ckeditor\plugins\image\dialogs中的image.js文件,找到如下代码的位置:
if ("true" == c.getCustomData("isReady"))
{
var d = a.getContentElement("info", "txtWidth"),
f = a.getContentElement("info", "txtHeight"), g;
b ? c = g = 0 : (g = c.$.width, c = c.$.height);
d && d.setValue(g); f && f.setValue(c)
}
将setValue
的值设置为null即可。然后刷新页面再上传图片就会发现默认值不存在了。
总结:这是目前为止,踩过的坑并找到的解决方案,期间阅读了不少次纯英文的API,实在是痛苦。大致来说,使用起来的流程如下:
下载完整版的插件,修改config.js并引入到项目中。将需要替换的div加上contenteditable="true"
,如果是SPA,还需要手动销毁所有已创建的实例,防止页面报错。难点是在图片上传,一定需要让后台配合修改。防止跨域,并返回指定的脚本内容。