ckeditor自定义按钮及阿里oss上传
<h4>啰嗦需求</h4><p>公司的百度编辑器已经千疮百孔了,各种bug层出不穷,因为公司图片这块的处理全是oss直传阿里的,上个前端也是费了巨力重新编辑修改了百度编辑器的图片上传功能,来贴合公司的实际需求。但是我觉得编辑器这块最重要是需要贴合用户的实际使用体验,编辑出来的页面是要在移动端展示的,最好能实现真正的“所见即所得”,傻瓜式的编辑体验,简单粗暴,够用就好,花里胡哨的功能我们也暂时用不到。参考了微信公众号编辑界面,知乎文章编辑界面,发现都是“简单”的界面实现了很“实用”的功能。<br />
接下来就是现有编辑器的选择了,毕竟自己现写个编辑器根本不现实(听说知乎的编辑器是30人的团队维护的…)。查阅了几家编辑器:wangEditor、bootstrap-wysiwyg、tinymce…感觉都对不上,不是文档太少,就是感觉“弱不经风”,官网的编辑器随手试试都能搞一两个bug出来,优化体验太差。应了知乎大神那句“编辑器是个坑,你们千万别往里跳”,一个好的编辑器真是需要精力去维护和更新的。<br />
最后选择了比较稳重的ckeditor,文档很全,支持插件,配置什么的也很友好,先给个文档链接感受一下:ckeditor在线文档https://docs.ckeditor.com/#!/guide/dev_installation</p>
<h4>安装配置</h4>
<p>官网下载文件,下载界面可选:Basic Package、Standard Package、Full Package、Customize。根据自己需求下载不同的安装包,而且每种都有压缩版和源码版可选。其中Customize版本顾名思义可自定义选择自己需要的模块,官方也推荐使用这种方式自定义下载,免得像我一样傻呵呵的自己下载需要的插件,结果安装依赖包安装到怀疑人生。<br />
接下来很简单,傻瓜式安装:</p>
<ul>
<li>
<p>html页面引入ckeditor.js文件,也可以使用官方CDN</p>
<table>
<tbody>
<tr>
<td><script type="text/javascript" src="ckeditor/ckeditor.js /> //<script src="https://cdn.ckeditor.com/4.7.2/standard/ckeditor.js"></script> //官方CDN</td>
</tr>
</tbody>
</table>
</li>
<li>
<p>替换textarea</p>
<table>
<tbody>
<tr>
<td><textarea name="editor1" id="editor1" rows="10" cols="80">This is my textarea to be replaced with CKEditor.</textarea></td>
</tr>
</tbody>
</table>
</li>
<li>
<p>实例化ckeditor</p>
<table>
<tbody>
<tr>
<td><script><br />
// Replace the <textarea id="editor1"> with a CKEditor<br />
// instance, using default configuration.<br />
CKEDITOR.replace( 'editor1' );<br />
</script></td>
</tr>
</tbody>
</table>
</li>
</ul>
<p>这样,一个基本可以使用的编辑器就搞好了,大概如下图:<br />
<img alt="截图1.png" src="data/attachment/forum/202309/29/297dfaa340080d62e2d2bf847cb1d96b.jpg" /></p>
<h4>个性化配置</h4>
<ul>
<li>
<p>ckeditor的个性化配置功能很人性化,打开下载好的ckeditor文件夹,ckeditor/samples/index.html打开,点击右上TOOLBAR CONFIGURATOR,切换到配置功能页,勾选自己需要的功能块儿,也可以调整显示顺序,上方是预览。<br />
<img alt="截图2.png" src="data/attachment/forum/202309/29/ec1d50aa842658777cfe1a3754fb2721.jpg" /></p>
</li>
<li>
<p>点击右边的Get toolbar config按钮,切换至我们配置好的config源码部分,复制该配置代码至ckeditor/config.js,直接覆盖就好。基本上所做的个性化配置都在这个文件里定义(还有另外两种配置方式,具体可以查看文档)。</p>
<table>
<tbody>
<tr>
<td>CKEDITOR.editorConfig = function( config ) {<br />
config.toolbarGroups = [<br />
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },<br />
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },<br />
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] },<br />
{ name: 'forms', groups: [ 'forms' ] },<br />
{ name: 'styles', groups: [ 'styles' ] },<br />
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },<br />
{ name: 'colors', groups: [ 'colors' ] },<br />
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi', 'paragraph' ] },<br />
{ name: 'links', groups: [ 'links' ] },<br />
{ name: 'insert', groups: [ 'insert' ] },<br />
{ name: 'tools', groups: [ 'tools' ] },<br />
{ name: 'others', groups: [ 'others' ] },<br />
{ name: 'about', groups: [ 'about' ] }<br />
];<br />
config.removeButtons = 'Image,Source,Save,NewPage,Print,Templates,PasteFromWord,PasteText,Paste,Copy,Cut,Find,Replace,SelectAll,Scayt,Form,Subscript,Superscript,CopyFormatting,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,Outdent,Indent,CreateDiv,BidiLtr,BidiRtl,Language,Anchor,Table,HorizontalRule,Smiley,SpecialChar,PageBreak,ShowBlocks,Blockquote,Styles,Font,Preview,Flash,Link,Unlink,Maximize,Format,About,Iframe';<br />
};</td>
</tr>
</tbody>
</table>
</li>
<li>
<p>刷新页面,就可以看到配置完的个性化编辑器了。</p>
</li>
</ul>
<h4>自定义按钮(功能)</h4>
<p>毕竟每个人的需求都是不一样的,这时候一个编辑器的“可扩展性”就必不可少了。上面说道,图片功能需要结合阿里的oss上传,policy,signature等等的验证,同时需要能有微信公众号编辑界面一样,实现图片的100%显示和原尺寸显示的自由切换。</p>
<ul>
<li>
<p>在ckeditor/plugins文件夹下,新建一个名为oss的文件夹:内含dialogs文件夹,存放我们的弹窗内容;images文件夹,用来存放用到的小图标;plugin.js文件,定义oss插件的入口。方便起见我就用代码模拟一下,不传图了。</p>
<table>
<tbody>
<tr>
<td>
<pre>
oss
...dialogs
......oss.js
...images
......xxx.jpg
......xxx.png
...plugin.js
</pre>
</td>
</tr>
</tbody>
</table>
</li>
<li>
<p>配置oss/plugin.js文件</p>
<table>
<tbody>
<tr>
<td>( function() {<br />
CKEDITOR.plugins.add( 'oss', {<br />
onLoad: function() {},<br />
init: function( editor ) { //上传图片插件初始化<br />
editor.addCommand('ossupload', new CKEDITOR.dialogCommand('ossupload')); //基于dialog弹窗插件<br />
editor.ui.addButton('oss',<br />
{<br />
label: '插入图片', //鼠标hover到按钮上显示文字<br />
icon: 'plugins/oss/images/oss.png', //自定义按钮的图标<br />
command: 'ossupload' //点击按钮执行的命令<br />
});<br />
// 注册右键菜单<br />
if ( editor.contextMenu ) {<br />
editor.addMenuGroup( 'oss');<br />
editor.addMenuItem( 'image', {<br />
label: '修改图片',<br />
command: 'ossupload',<br />
group: 'oss'<br />
} );<br />
}<br />
CKEDITOR.dialog.add( 'ossupload', this.path + 'dialogs/oss.js' ); //弹窗文件,指向dialogs文件夹下的oss.js<br />
},<br />
afterInit: function() {}<br />
} );<br />
} )();</td>
</tr>
</tbody>
</table>
</li>
</ul>
<p>接下来定义弹窗的内容,即dialogs内的oss.js文件,先看下实际效果<br />
<img alt="编辑器1.png" src="data/attachment/forum/202309/29/a1dfd8cee92486644ab45cbb37260bbc.jpg" /></p>
<table>
<tbody>
<tr>
<td>CKEDITOR.dialog.add( 'ossupload', function( editor ) {<br />
// 图片尺寸html模板<br />
var sizeHtml = new CKEDITOR.template( '<div class="myradio">' +<br />
'<div class="item" style="padding-bottom:5px;">'+<br />
'<input type="radio" name="size" value="100%" id="100" checked style="vertical-align:middle;margin:0 5px 0 0;">' +<br />
'<label for="100">图片满屏显示</label>'+<br />
'</div>'+<br />
'<div class="item">'+<br />
'<input type="radio" name="size" value="auto" id="auto" style="vertical-align:middle;margin:0 5px 0 0;">' +<br />
'<label for="auto">图片原尺寸显示</label>'+<br />
'</div>'+<br />
'</div>').output();<br />
var currentSrc = null; //编辑时图片源地址<br />
// 阿里oss图片上传<br />
function plupload1() {<br />
//阿里oss上传组件,使用了官网的例子,基于plupload组件<br />
};<br />
return {<br />
title: '插入图片',<br />
width: 302, //弹窗的宽px<br />
minHeight: 302, //弹窗的最小高度px,上传图片高度大于300自动撑开<br />
contents: [<br />
{<br />
id: 'ossimage',<br />
label: '上传图片',<br />
elements: [ //自定义弹窗的内容,可以使用模板,也可自定义html及样式<br />
{<br />
id: 'myimage', //选择图片按钮<br />
type: 'html',<br />
html: '<a href="javascript:;" id="selectfile">选择图片</a>', //plupload按钮<br />
style: 'display:block;width:82px;line-height:34px;background-color:#3366b7;font-size:14px;color:#fff;text-align:center;border-radius:4px;', //html的样式,直接作用于上面的a元素<br />
onShow: function() { //当该元素show的时候执行的方法<br />
if(currentSrc && currentSrc !== 'undefined'){ //当右键编辑图片时执行,下篇说<br />
$('#selectfile').hide();<br />
$('.moxie-shim').hide();<br />
}<br />
},<br />
onLoad: function() {<br />
plupload1(); //加载时实例化plupload上传组件<br />
}<br />
},<br />
{<br />
type: 'html', //图片上传成功后的容器<br />
html: '<div class="container"><div class="imgbox"></div><a style="display:none;position:absolute;top:0;left:0;z-index:1;width:16px;height:16px;background-image:url(/assets/js/ckeditor/skins/moono-lisa/images/close2.png)"></a></div>',<br />
style: 'width:300px;height:auto;position:relative;', //对应的样式<br />
onShow: function() {<br />
if(currentSrc && currentSrc !== 'undefined'){<br />
//右键编辑图片时,将图片src传入容器,同时注册关闭图片事件<br />
}<br />
},<br />
commit: function( editor ){ //点击确定按钮时,将图片src传入全局src中<br />
src = $('.imgbox img').attr('src');<br />
}<br />
},<br />
{<br />
id: 'size', //图片全屏显示及按实际尺寸显示radio<br />
type: 'html',<br />
html: sizeHtml, //html写到了上面<br />
commit: function( editor ){<br />
var tt = document.getElementsByName('size'); //取radio选项<br />
for (var i = 0; i < tt.length ; i++ ){ <br />
if(tt.checked){<br />
imgsize = tt.value; <br />
break;<br />
}<br />
}<br />
if(src != undefined){<br />
//创建element,即确定后填到编辑器中的代码,此处最好使用p标签包裹img标签,ckeditor都是使用p标签包裹元素,保持一致<br />
var ele = CKEDITOR.dom.element.createFromHtml( '<p style="padding:5px 0;"><img style="max-width: 100%;width:'+imgsize+'" src="'+src+'"/></p>' ); <br />
editor.insertElement(ele); //将element插入editor<br />
}<br />
}<br />
}<br />
]<br />
}<br />
],<br />
onShow: function() {<br />
currentSrc = null; //弹窗显示的时候判断‘选中元素’的currentSrc是否存在<br />
var element = editor.getSelection().getSelectedElement();<br />
if(element){<br />
console.log(element);<br />
console.log(element.$.currentSrc);<br />
currentSrc = element.$.currentSrc;//源图片地址<br />
}<br />
},<br />
onOk: function () {<br />
this.commitContent(editor);<br />
//点击确定时dom操作<br />
currentSrc = null;<br />
},<br />
onCancel: function () {<br />
//取消时dom操作<br />
currentSrc = null; //取消或者确定时清空currentSrc<br />
}<br />
};<br />
} );</td>
</tr>
</tbody>
</table>
<p>看下上传图片后的实际效果<br />
<img alt="编辑器2.png" src="data/attachment/forum/202309/29/6ecd6b9f760c3e0f17366057b2c8c85c.jpg" /></p>
<p><img alt="编辑器3.png" src="data/attachment/forum/202309/29/551f4609c8befb45adaedefe608944e6.jpg" /></p>
<p>图片满屏显示会将图片宽度设为100%,高度自动;图片原尺寸显示会显示图片原本的尺寸。这里注意所谓图片原尺寸是指图片的实际大小,假若图片宽度200px,那么图片不管在什么设备下,宽度始终为200px,不过若是图片原尺寸超过了设备的实际宽度,那么图片的最大宽度就是设备的宽度,不会出现左右滚动条。</p>
<p>最后记得将我们自定义的组件注册到config.js中</p>
<table>
<tbody>
<tr>
<td>config.extraPlugins = 'myi frame,oss,dialog,dialogui,lineheight,richcombo,floatpanel,panel,listblock'; //除了oss,myi frame,lineheight外,其他都为依赖组件</td>
</tr>
</tbody>
</table>
<p> </p>
<p>最后是编辑器的一些其他优化,如使用rem使编辑器宽度,字体大小等比例显示,行高组件的添加等,都是为了真正的实现所见即所得的个性化移动编辑器,真正做到了pc端编辑出来的效果就是在移动展示的实际比例效果。</p>
<table>
<tbody>
<tr>
<td>config.fontSize_defaultLabel = '12';<br />
config.fontSize_sizes='12/0.24rem;14/0.28rem;16/0.32rem;18/0.36rem;20/0.4rem;22/0.44rem;24/0.48rem;26/0.52rem;28/0.56rem;36/0.72rem;48/0.96rem;72/1.44rem';<br />
CKEDITOR.config.menu_groups = ''; //编辑器内的右键菜单设为空。搜索关键字menuitem,查看源码<br />
config.line_height = '1;1.2;1.5;2;2.2;2.5;3;3.5;4;5'; //定义行高</td>
</tr>
</tbody>
</table>
<p>源文地址:https://liyang0207.github.io/2017/08/22/ckeditor%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8C%89%E9%92%AE%E5%8F%8A%E9%98%BF%E9%87%8Coss%E4%B8%8A%E4%BC%A0/</p>
<br />
<br />
页:
[1]