CKEditor扩展插件:自动排版功能autoformat插件实现方法详解


Posted in Javascript onFebruary 06, 2020

本文实例讲述了CKEditor扩展插件:自动排版功能autoformat插件实现方法。分享给大家供大家参考,具体如下:

1.注册插件

首先找到根目录下的ckeditor/config.js文件,打开文件如下:

CKEDITOR.editorConfig = function (config) {
 // Define changes to default configuration here. For example:
 // config.language = 'fr';
 // config.uiColor = '#AADC6E';
};

我们需要将我们的插件注册进CKEDITOR中。

在方法内部加入如下代码:

config.extraPlugins = "autoformart";

如果值中有其他字符,则用","逗号分隔,增加.

2.创建Plugin.js文件

在Plugins文件下新建一个与插件名相同的文件夹:aotuformart 的文件夹,意为自动排版。

再在文件夹内创建一个plugin.js文件,因为在注册插件后,首先加载和执行的就是plugin.js这个文件。

首先我们构建一个自执行函数,在自执行函数中添加一个插件:

(function()
{
 CKEDITOR.plugins.add('autoformat',{
  init:function(editor){
  //初始化操作
  }
 });
})();

添加一个命令和按钮在初始化函数中,如下:

(function()
{
 CKEDITOR.plugins.add('autoformat',{
  init:function(editor){
   editor.addCommand( 'autoformat', new CKEDITOR.autoformatCommand());
   editor.ui.addButton('Autoformat',{label:'自动排版',command:'autoformat',icon:CKEDITOR.getUrl( this.path + 'images/autoformat.png' )});
  }
 });
})();

addCommand方法有两个参数:插件命令名称,第二个是命令执行的方法。

addButton方法的第一个参数是:插件的按钮名称

label:鼠标悬浮时插件提示

command:执行插件命令的名称

icon:插件图标

所有代码(上边的两块代码为演示注册插件)

//一键排版
(function () {
 CKEDITOR.plugins.add('autoformat', {
  requires: ['styles', 'button'],
  init: function (a) {
   a.addCommand('autoformat', CKEDITOR.plugins.autoformat.commands.autoformat);
   a.ui.addButton('autoformat', {
    label: "一键排版",
    command: 'autoformat',
    icon: this.path + "images/autoformat.png"
   });
  }
 });
 CKEDITOR.plugins.autoformat = {
  commands: {
   autoformat: {
    exec: function (editor) {
     formatText(editor);
    }
   }
  }
 };
 //格式化
 function formatText(editor) {
  var myeditor = editor;
  if (myeditor.mode == "wysiwyg") {
   var tempimg = new Array();
   var temptable = new Array();
   var tempobject = new Array();
   var isPart = false; //暂时无法实现局部格式化
   if (!isPart) {
    var tmpDiv = document.createElement("DIV");
    var editorhtml = myeditor.getData();
    editorhtml = editorhtml.replace(/<div style="page-break-after: always;?">\s*<span style="display: none;?"> <\/span>\s*<\/div>/gi, '<p>[ page]</p>'); //将div span标签替换为p 标签
    tmpDiv.innerHTML = editorhtml.replace(/ /gi, '').replace(/<div/gi, '<p').replace(/<\/div/gi, '</p');  //移除空格标签,div替换为p标签。
    if (window.navigator.userAgent.toLowerCase().indexOf("msie") > 0) {
     tmpDiv.innerHTML = tmpDiv.innerHTML.replace(/<\/p>/gi, '<br /><\/p>');  //每个段落相隔一行
    }
    var tables = tmpDiv.getElementsByTagName("TABLE");
    if (tables != null && tables.length > 0) {
     for (var j = 0; j < tables.length; j++) {
      temptable[temptable.length] = tables[j].outerHTML;
     }
     var formattableCount = 0;
     for (var j = 0; j < tables.length;) {
      tables[j].outerHTML = "#FormatTableID_" + formattableCount + "#";
      formattableCount++;
     }
    }
    var objects = tmpDiv.getElementsByTagName("OBJECT");
    if (objects != null && objects.length > 0) {
     for (var j = 0; j < objects.length; j++) {
      tempobject[tempobject.length] = objects[j].outerHTML;
     }
     var formatobjectCount = 0;
     for (var j = 0; j < objects.length;) {
      objects[j].outerHTML = "#FormatObjectID_" + formatobjectCount + "#";
      formatobjectCount++;
     }
    }
    var imgs = tmpDiv.getElementsByTagName("IMG");
    if (imgs != null && imgs.length > 0) {
     for (var j = 0; j < imgs.length; j++) {
      var t = document.createElement("IMG");
      t.alt = imgs[j].alt;
      t.src = imgs[j].src;
      t.width = imgs[j].width;
      t.height = imgs[j].height;
      t.align = imgs[j].align;
      tempimg[tempimg.length] = t;
     }
     var formatImgCount = 0;
     for (var j = 0; j < imgs.length;) {
      imgs[j].outerHTML = "#FormatImgID_" + formatImgCount + "#";
      formatImgCount++;
     }
    }
    var strongarray = new Array();
    var strongcount = 0;
    for (var i = 0; i < tmpDiv.getElementsByTagName('b').length; i++) {
     strongarray[strongcount] = tmpDiv.getElementsByTagName('b')[i].innerText.trim();
     tmpDiv.getElementsByTagName('b')[i].innerHTML = "#FormatStrongID_" + strongcount + "#";
     strongcount++;
    }
    for (var i = 0; i < tmpDiv.getElementsByTagName('strong').length; i++) {
     strongarray[strongcount] = tmpDiv.getElementsByTagName('strong')[i].innerText.trim();
     tmpDiv.getElementsByTagName('strong')[i].innerHTML = "#FormatStrongID_" + strongcount + "#";
     strongcount++;
    }
    var html = processFormatText(tmpDiv.innerText);
    html = html.replace(/<p>\[ page\]<\/p>/gi, '<div style="page-break-after: always;"><span style="display: none;"> </span></div>'); //p标签替换回原来的div和span标签。
    if (temptable != null && temptable.length > 0) {
     for (var j = 0; j < temptable.length; j++) {
      var tablehtml = temptable[j];
      html = html.replace("#FormatTableID_" + j + "#", tablehtml);
     }
    }
    if (tempobject != null && tempobject.length > 0) {
     for (var j = 0; j < tempobject.length; j++) {
      var objecthtml = "<p align=\"center\">" + tempobject[j] + "</p>";
      html = html.replace("#FormatObjectID_" + j + "#", objecthtml);
     }
    }
    if (tempimg != null && tempimg.length > 0) {
     for (var j = 0; j < tempimg.length; j++) {
      var imgheight = "";
      var imgwidth = "";
      if (tempimg[j].height != 0)
       imgheight = " height=\"" + tempimg[j].height + "\"";
      if (tempimg[j].width != 0)
       imgwidth = " width=\"" + tempimg[j].width + "\"";
      var imgalign = "";
      if (tempimg[j].align != "")
       imgalign = " align=\"" + tempimg[j].align + "\"";
      var imghtml = "<p align=\"center\"><img src=\"" + tempimg[j].src + "\" alt=\"" + tempimg[j].alt + "\"" + imgwidth + " " + imgheight + " align=\"" + tempimg[j].align + "\" border=\"0\"></p>";
      html = html.replace("#FormatImgID_" + j + "#", imghtml);
     }
    }
    for (var i = 0; i < strongcount; i++) {
     html = html.replace("#FormatStrongID_" + i + "#", "<p><strong>" + strongarray[i] + "</strong></p>");
    }
    while (html.indexOf("</p></p>") != -1) html = html.replace("</p></p>", "</p>");
    while (html.indexOf('<p><p align="center">') != -1) html = html.replace('<p><p align="center">', '<p align="center">');
    editor.setData(html);
   } else {
   }
  } else {
   alert('必须在设计模式下操作!');
  }
 }
 function processFormatText(textContext) {
  var text = dbc2Sbc(textContext);
  var prefix = "";
  var tmps = text.split("\n");
  var html = "";
  for (var i = 0; i < tmps.length; i++) {
   var tmp = tmps[i].trim();
   if (tmp.length > 0) {
    var reg = /#Format[A-Za-z]+_\d+#/gi;
    var f = reg.exec(tmp);
    if (f != null) {
     tmp = tmp.replace(/#Format[A-Za-z]+_\d+#/gi, '');
     html += f;
     if (tmp != "")
      html += "<p align=\"center\">" + tmp + "</p>\n";
    } else {
     html += "<p style='text-indent:2em;'>" + tmp + "</p>\n";
    }
   }
  }
  return html;
 }
 function dbc2Sbc(str) {
  var result = '';
  for (var i = 0; i < str.length; i++) {
   var code = str.charCodeAt(i);
   // “65281”是“!”,“65373”是“}”,“65292”是“,”。不转换","
   if (code >= 65281 && code < 65373 && code != 65292 && code != 65306) {
    // “65248”是转换码距
    result += String.fromCharCode(str.charCodeAt(i) - 65248);
   } else {
    result += str.charAt(i);
   }
  }
  return result;
 }
 String.prototype.trim = function () {
  return this.replace(/(^[\s ]*)|([\s ]*$)/g, "");
 };
 String.prototype.leftTrim = function () {
  return this.replace(/(^\s*)/g, "");
 };
 String.prototype.rightTrim = function () {
  return this.replace(/(\s*$)/g, "");
 };
})();

3、配置到菜单中

例basic模式:

['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink' ],['Maximize']

改为

['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink' ],['Maximize','autoformat']

4、图标

当前占位已经实现,但由于没有图标,显示上会有问题,此时自己找或制作一个图标,放到autoformat/images/下命名为autoformat.png

借用某编辑器的:CKEditor扩展插件:自动排版功能autoformat插件实现方法详解

如未生效,记得清除cookie或更换浏览器查看显示效果。

5、效果对比

CKEditor扩展插件:自动排版功能autoformat插件实现方法详解

CKEditor扩展插件:自动排版功能autoformat插件实现方法详解

希望本文所述对大家CKEDitor富文本编辑器开发有所帮助。

Javascript 相关文章推荐
JQuery 选择器 xpath 语法应用
May 13 Javascript
Javacript实现颜色梯度变化和渐变的效果代码
May 31 Javascript
JavaScript的Date()方法使用详解
Jun 09 Javascript
jquery实现的树形目录实例
Jun 26 Javascript
JavaScript中this的用法及this在不同应用场景的作用解析
Apr 13 Javascript
Angular2使用jQuery的方法教程
May 28 jQuery
js判断用户是输入的地址请求的路径(实例讲解)
Jul 18 Javascript
Vue + Vue-router 同名路由切换数据不更新的方法
Nov 20 Javascript
webpack项目轻松混用css module的方法
Jun 12 Javascript
layui异步加载table表中某一列数据的例子
Sep 16 Javascript
JS正则表达式验证端口范围(0-65535)
Jan 06 Javascript
js实现弹窗效果
Aug 09 Javascript
JS实现盒子拖拽效果
Feb 06 #Javascript
JavaScript实现拖拽盒子效果
Feb 06 #Javascript
JS实现“全选”和&quot;全不选&quot;功能代码实例
Feb 06 #Javascript
JavaScript实现好看的跟随彩色气泡效果
Feb 06 #Javascript
详细介绍解决vue和jsp结合的方法
Feb 06 #Javascript
如何在vue项目中嵌入jsp页面的方法(2种)
Feb 06 #Javascript
js get和post请求实现代码解析
Feb 06 #Javascript
You might like
基于文本的访客签到簿
2006/10/09 PHP
php银联网页支付实现方法
2015/03/04 PHP
PHP编程计算文件或数组中单词出现频率的方法
2017/05/22 PHP
php实现微信企业号支付个人的方法详解
2017/07/26 PHP
php实现socket推送技术的示例
2017/12/20 PHP
PHP+redis实现的悲观锁机制示例
2018/06/12 PHP
PHP压缩图片功能的介绍
2019/03/21 PHP
tp5.1 框架join方法用法实例分析
2020/05/26 PHP
jQuery中add实现同时选择两个id对象
2010/10/22 Javascript
用javascript模仿ie的自动完成类似自动完成功的表单
2012/12/12 Javascript
判断文件是否正在被使用的JS代码
2013/12/21 Javascript
微信小程序 MINA文件结构
2016/10/17 Javascript
简单实现JavaScript图片切换效果
2016/11/28 Javascript
解决BootStrap Fileinput手机图片上传显示旋转问题
2017/06/01 Javascript
解决js ajax同步请求造成浏览器假死的问题
2018/01/18 Javascript
vue单页缓存存在的问题及解决方案(小结)
2018/09/25 Javascript
layui form表单提交之后重新加载数据表格的方法
2019/09/11 Javascript
解决Antd Table组件表头不对齐的问题
2020/10/27 Javascript
python3实现windows下同名进程监控
2018/06/21 Python
Python 占位符的使用方法详解
2019/07/10 Python
python实现快递价格查询系统
2020/03/03 Python
Django REST 异常处理详解
2020/07/15 Python
阿提哈德航空官方网站:Etihad Airways
2017/01/06 全球购物
生产经理的自我评价分享
2013/11/07 职场文书
应届生法律顾问求职信
2013/11/19 职场文书
车间统计员岗位职责
2014/01/05 职场文书
公司业务员岗位职责
2014/03/18 职场文书
小学一年级学生评语
2014/04/22 职场文书
财会专业大学生求职信
2014/09/26 职场文书
教师个人自我剖析材料
2014/09/29 职场文书
市委常委班子党的群众路线教育实践活动整改措施
2014/10/02 职场文书
工商局个人工作总结
2015/03/03 职场文书
刑事上诉状范文
2015/05/22 职场文书
优秀共产党员事迹材料2016
2016/02/29 职场文书
导游词范文之颐和园/重庆/云台山
2019/09/10 职场文书
导游词之云南丽江-泸沽湖
2019/09/26 职场文书