关于CKEditor4.5.6的使用,自定义toolbar配置,上传图片案例(SpringMVC+MyBatis案例),自定义行高,去编辑器的中内容,将编辑器中内容设置到指定的位置等
关于CKEditor的一个配置整理,改文件为config.js:
文件内容如下:
/** CKEDITOR.editorConfig = function( config ) { |
关于图片上传部分可以参考:
http://blog.csdn.net/itmyhome1990/article/details/17264627
实现过程中的一个案例
/* * name :tuzuoquan * mail :tuzq@XXXX.cn * date :2016/01/13 * version :1.0 * description:XXXXXX对应的js * CopyRight (C) 2015-12-31 */ if (CKEDITOR.env.ie && CKEDITOR.env.version < 9) CKEDITOR.tools.enableHtml5Elements(document); /** * 编辑器对应的操作方法 * * 关于在线编辑器的文档:http://sdk.ckeditor.com/samples/resize.html */ var CKEDITORHandler = (function($) { return { /** * 初始化参数配置 */ ckeditorConfig:function(){ //去掉开始进来的时候自动添加 BR CKEDITOR.config.enterMode = CKEDITOR.ENTER_BR; //去掉开始进来的时候自动添加P CKEDITOR.config.shiftEnterMode = CKEDITOR.ENTER_P; CKEDITOR.config.font_names='微软雅黑;宋体;新宋体;黑体;隶书;幼圆;楷体_GB2312;仿宋_GB2312;方正舒体;方正姚体;华文隶书;华文新魏;华文行楷;sans-serif;Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana;' CKEDITOR.config.line_height="1em;1.1em;1.2em;1.3em;1.4em;1.5em"; }, /** * 初始化工具条的相关信息 */ initToolBar:function(){ CKEDITOR.config.toolbar = 'Full'; /** * 其中("-")为空间栏的水平分割,("/")为换行 * * 以下:Full表示的所有的操作 */ CKEDITOR.config.toolbar_Full = [ { 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: 'links', groups: [ 'links' ] }, { name: 'insert', groups: [ 'insert' ] }, { name: 'colors', groups: [ 'colors' ] }, { name: 'styles', groups: [ 'styles' ] }, { name: 'tools', groups: [ 'tools' ] }, { name: 'paragraph', groups: [ 'list', 'blocks', 'bidi', 'align', 'indent', 'paragraph' ] }, { name: 'others', groups: [ 'others' ] }, { name: 'about', groups: [ 'about' ] } ]; CKEDITOR.config.toolbar_Basic = [ ['Source','Preview'], ['Cut','Copy','Paste','PasteText','PasteFromWord','-','SpellChecker'], ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], ['NumberedList','BulletedList','-','Outdent','Indent'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['Link','Unlink','Anchor'], ['Image','Flash','Table','SpecialChar'], ['Styles','Format','Font','FontSize'], ['TextColor','BGColor'], ['lineheight'] ]; }, /** * 在线编辑器的初始化过程 * textContent :表示的是文本组件的内容 */ init:function(textContent){ //注意:这里的tpl-content-editor是编辑器对应的id值 if(CKEDITOR.instances.tplContentEditor) { var editor = CKEDITOR.instances["tplContentEditor"]; //console.log("1------------------------------------------"); //console.log(editor.getData()); //editor.setData(editor.setData(textContent)); //console.log("2------------------------------------------"); //销毁编辑器,然后新增一个 if(editor) editor.destroy(true); } CKEDITORHandler.ckeditorConfig(); //初始化工具栏 CKEDITORHandler.initToolBar(); CKEDITOR.replace("tplContentEditor", { toolbar:'Basic', height:'300', width:'auto' }); //为编辑器设置内容 CKEDITOR.instances.tplContentEditor.setData(textContent); }, /** * 2、判断一个字符串变量是否为空 * 如果不为空:返回true * 如果为空:返回false */ isNotBlank:function(variable){ return (variable != null && typeof(variable) != "undefined" && variable != undefined && variable != "") ? true : false; }, /** * 通过编辑的icon获得组件元素,查找父元素,直到找到含有className这个类选择器的元素停止 * domEle :表示的是编辑的元素 */ /** * 将str1这个原始的字符串中的str2全部换成str3 * str1 :最原始的字符串 * str2 :要被替换的字符串 * str3 :最终替换成的字符串 * * 此外可以增加String对象的原型方法: * String.prototype.replaceAll = function(str2,str3){ * return this.replace(new RegExp(str2,"gm"),str3); * } */ replaceAll:function(str1,str2,str3) { var newStr = str1; if(this.isNotBlank(str1)) { //其中gm中的g表示"执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)" //其中gm中的m表示执行多行匹配 newStr = str1.replace(new RegExp(str2,"gm"),str3); } return newStr; }, /** * 清除样式 */ removeCss:function(id,childPathOfSelectedElement,cssType){ //替换原来的css样式 var oldStyleCss = $("#generatedCss").html().replace( new RegExp("#"+ id + childPathOfSelectedElement + ".*?{.*"+cssType+".*?}"),""); oldStyleCss = this.replaceAll(oldStyleCss,"\r\n",""); $("#generatedCss").text(oldStyleCss); }, obtainComponentEle:function(domEle,className) { var tempObj = domEle; while(!$(tempObj).parent().hasClass(className)) { tempObj = $(tempObj).parent().get(0); } return $(tempObj).parent().get(0); }, /** * 存储的是要编辑的对象 */ editObj : null, /** * 表示的是否是多列的 */ isMultiseriate : false, /** * 1、点击编辑按钮的时候执行的操作 * domEle :代表的是编辑按钮 * selectedElementInfo :表示的是被选中的元素 * childPathOfSelectedElement :表示的是放置内容的位置 * * isMultiseriate :表示的是是否多列 * obj :表示的是被点击的个元素 * * 如果是单列的: * 比如点击"text"组件"编辑"按钮的时候传递进入的参数是:(this,selectedElementInfo,'',false,'') * 如果实在配置文件中点击弹出的,传递的参数是:('',selectedElementInfo,' .xxx .xxx',false,''),其中' .xxx .xxx'是你要改变的元素 * * 如果是多列的: * ('',selectedElementInfo,'',true,editObj) */ tplEditSelectedContent:function(domEle,selectedElementInfo,childPathOfSelectedElement,isMultiseriate,editObj) { //存储的是点击的对象 CKEDITORHandler.editObj = editObj; //存储是否是多列的情况 CKEDITORHandler.isMultiseriate = isMultiseriate; //如果是多列的 if(CKEDITORHandler.isMultiseriate) { //获得要编辑的元素的内容: var textContent = $(CKEDITORHandler.editObj).html(); } else { //获得domEle这个编辑按钮的组件 var componentEle = null; if(CKEDITORHandler.isNotBlank(domEle)) { componentEle = CKEDITORHandler.obtainComponentEle(domEle,"tpl-monitored-class"); } else { var id = selectedElementInfo.get("id"); componentEle = $("#" + id); } //将当前元素的id存储到隐藏域中 $(".tpl-edit-popup-window #componentId").val($(componentEle).attr("id")); //存储要设置的元素的值 if(!CKEDITORHandler.isNotBlank($.trim(childPathOfSelectedElement))) { childPathOfSelectedElement = " .tpl-component-2015-12-30-text-content"; } //将要编辑的后代的值存到隐藏域中 $(".tpl-edit-popup-window #childPathOfSelectedElement").val(childPathOfSelectedElement); //获得当前要编辑的元素的id var componentId = $(componentEle).attr("id"); //获得要编辑的元素的内容: var textContent = $("#" + componentId + " " + childPathOfSelectedElement).html(); } //获得文本组件中的内容 CKEDITORHandler.init(textContent); $('.theme-popover-mask').fadeIn(10); $('.theme-popover').slideDown(20); }, /** * 点击取消的时候执行的动作 * @return */ tplEditCancel:function() { $('.theme-popover-mask').fadeOut(100); $('.theme-popover').slideUp(200); }, /** * 点击"确定的时候执行的动作" * @return */ tplEditOk:function() { //获得编辑器中的内容 var editorContent = CKEDITOR.instances.tplContentEditor.getData(); var id = selectedElementInfo.get("id"); /** * 判断是否是多列的 */ if(CKEDITORHandler.isMultiseriate) { $(CKEDITORHandler.editObj).empty(); $(CKEDITORHandler.editObj).append(editorContent); } else { //1、首先判断编辑器内容中第一个子标签的内容是否是<pre>,若是,则在后面不在添加<pre> //$("<div></div>").append(editorContent).first().prop("tagName"); //$("<div></div>").append(editorContent).first().prop("nodeName"); //获得要修改的组件的id var componentId = $(".tpl-edit-popup-window #componentId").val(); //获得组件中要放置内容的元素 var childPathOfSelectedElement = $(".tpl-edit-popup-window #childPathOfSelectedElement").val(); $("#" + componentId + " " + childPathOfSelectedElement).empty(); $("#" + componentId + " " + childPathOfSelectedElement).append(editorContent); } if($("#" + id + " .picturegroup #topMarquee_1 li").length>0){ var currCount = $("#" + id + " .picturegroup #topMarquee_1 li").length; var baseHeight = 0; var i=0; for(;i<currCount;i++){ baseHeight += $("#" + id + " .picturegroup #topMarquee_1 li").eq(i).outerHeight(true); } var dyHeight = baseHeight + 'px'; var divHeight = baseHeight * 2 + 'px'; $("#" + id + " .picturegroup .picture-holder").css("height", dyHeight); $("#" + id + " .picturegroup div").css("height", divHeight); } /*if($("#" + id + " .picturegroup #erwm").length>0){ this.removeCss(id," .picturegroup","height"); this.removeCss(id," .picturegroup #erwm","height"); var height = parseFloat($("#picHeight").val()); var spanHeight = $("#" + id + " .picturegroup #erwm .bottomContent").height(); console.log(spanHeight); $("#" + id + " .picturegroup").css("height","'+(height+spanHeight)+'+'px'"); $("#" + id + " .picturegroup #erwm").css("height","'+(height+spanHeight)+'+'px'"); }*/ $('.theme-popover-mask').fadeOut(100); $('.theme-popover').slideUp(200); //恢复默认值 CKEDITORHandler.isMultiseriate = false; CKEDITORHandler.editObj = null; } } })(jQuery); /** * 1、页面加载完成后执行的动作 */ $(function(){ $('.theme-poptit .close').click(function(){ $('.theme-popover-mask').fadeOut(100); $('.theme-popover').slideUp(200); }); }); |
关于图片上传的后台操作,使用的框架是Spring+SpringMVC+MyBatis
package XXX.controller.upload; import org.apache.log4j.Logger; @Controller @RequestMapping(value = "/import", method = { RequestMethod.GET,RequestMethod.POST }) public class ImportController extends BaseController{ /** 用于打印日志 */ private static final Logger logger = Logger .getLogger(SpecialController.class); /** * 此方法用于CKEditor的本地上传图片的功能 * * @param param * @param imageFile * @return */ @RequestMapping(value = "/ckeditorUploadFile", produces = "text/json") public void ckeditorUploadFile( @RequestParam("upload") MultipartFile upload, HttpServletRequest request, HttpServletResponse response, @RequestParam("CKEditorFuncNum")String CKEditorFuncNum) throws IllegalStateException,IOException { PrintWriter out = response.getWriter(); response.setCharacterEncoding("utf-8"); //判断扩展文件名是否正确 String uploadContentType = upload.getContentType(); if(uploadContentType.equals("image/pjpeg") || uploadContentType.equals("image/jpeg")) { } else if(uploadContentType.equals("image/png") || uploadContentType.equals("image/x-png")) { } else if(uploadContentType.equals("image/gif")) { } else if(uploadContentType.equals("image/bmp")) { } else { out.println("<script type=\"text/javascript\">"); out.println("window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ",''," + "'文件格式不正确(必须为.jpg/.gif/.bmp/.png文件)');"); out.println("</script>"); return; } if (!upload.isEmpty()) { try { //如果上传的图片大于10M,返回提示 if (upload.getSize() > 10 * 1024 * 1024) { out.println("<script type=\"text/javascript\">"); out.println("window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ",''," + "'文件大小不得大于600k');"); out.println("</script>"); return; } Calendar calendar = Calendar.getInstance();//获取当前时间 //时间路径,解压文件,以年月日创建文件夹 String dataPath ="/"+calendar.get(Calendar.YEAR)+"/" + (calendar.get(Calendar.MONTH)+1)+"/" + calendar.get(Calendar.DATE)+"/"; // 原文件名 String srcName = upload.getOriginalFilename(); //获取上传文件后缀 String suffix = srcName.substring(srcName.lastIndexOf(".") + 1, srcName.length()).toLowerCase(); //随机生成32位id,用于解压文件目录 String uuid = UUIDGenerator.generate(); //新的文件名,随机的uuid; String picName = uuid +"."+suffix; //图片存储的实际路径 String urlPrefix = ExtendedServerConfig.getInstance().getStringProperty("VISITE_PREFIX_URL"); //大图缩略图生成路径 String thumbnailPath =ExtendedServerConfig.getInstance() .getStringProperty("THUMBNAIL_PATH")+ ExtendedServerConfig.getInstance() .getStringProperty("SAVE_BIG_THUMBNAIL")+dataPath; //生成缩略图保存数据库路径 String savePath =ExtendedServerConfig.getInstance() .getStringProperty("SAVE_BIG_THUMBNAIL")+dataPath+picName; //文件夹不存在,则创建 File destfile = new File(thumbnailPath); if(!destfile.exists()){ destfile.mkdirs(); } // 写文件 InputStream fi = upload.getInputStream(); //上传文件写入到配置文件夹下 FileUtils.writeFile(fi, thumbnailPath+picName); File file = new File(thumbnailPath+picName); if(file.exists()) { out.println("<script type=\"text/javascript\">"); out.println("window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ",'" + urlPrefix + savePath + "','')"); out.println("</script>"); return; } } catch (Exception e) { e.printStackTrace(); } } return; } } |
关于CKEditor4.5.6的使用,自定义toolbar配置,上传图片案例(SpringMVC+MyBatis案例),自定义行高,去编辑器的中内容,将编辑器中内容设置到指定的位置等的更多相关文章
- 自定义ToolBar之一
其实已经有很多大神写过这方面的文章了,不过我比较蠢吧,老有一些地方看不懂的,翻了很多关于Toolbar方面的文章和视频,这儿总结一下. 参考资料:youtube:slidenerd 阶段一 自定义配 ...
- 如何解决自定义ToolBar起始位置的空格(左对齐)问题
最近在做项目的时候,与到自定义toolbar的问题,自定义toolbar布局之类的并不是很难,但是自定义布局完成之后,控件总是无法左对齐,这极大的影响了App的美观. 结果谷歌后在Stack Over ...
- 商城项目实战 | 2.2 Android 仿京东商城——自定义 Toolbar (二)
本文为菜鸟窝作者刘婷的连载."商城项目实战"系列来聊聊仿"京东淘宝的购物商城"如何实现. 上一篇文章<商城项目实战 | 2.1 Android 仿京东商城 ...
- 自定义ToolBar
一.Toolbar的简介 Toolbar 是 android 5.0 引入的一个新控件,Toolbar出现之前,我们很多时候都是使用ActionBar以及ActionActivity实现顶部导航栏的, ...
- 去除自定义Toolbar中左边距
问题 自定义Toolbar之后,发现左侧不能完全填充,总是留一点空白,如下图: 原因 查看Wiget.AppCompat.Toolbar的parent(Toolbar默认的style),如下: < ...
- 【.net 深呼吸】自定义缓存配置(非Web项目)
在前一篇烂文中,老周简单讲述了非Web应用的缓存技术的基本用法.其实嘛,使用系统默认方案已经满足我们的需求了,不过,如果你真想自己来配置缓存,也是可以的. 缓存的自定义配置可以有两种方案,一种是用代码 ...
- Android之Toolbar的三个问题:修改左边箭头颜色、怎样修改右边以及子activity中的toolbar添加返回箭头
1)怎样修改左边这个小箭头的颜色? 2)怎样修改右边这三个点的颜色.怎样把这三个点替换成我自己的图标? 3)怎样让"交易清单"这4个字居中显示? 首先设置Theme为AppComp ...
- iOS开发——UI进阶篇(三)自定义不等高cell,如何拿到cell的行高,自动计算cell高度,(有配图,无配图)微博案例
一.纯代码自定义不等高cell 废话不多说,直接来看下面这个例子先来看下微博的最终效果 首先创建一个继承UITableViewController的控制器@interface ViewControll ...
- phpstorm 自定义函数配置
phpstorm 自定义函数配置 打开设置->活动模板->
随机推荐
- 未能加载 global.asax的类的解决方案
“/suitecallback”应用程序中的服务器错误. 分析器错误 说明: 在分析向此请求提供服务所需资源时出错.请检查下列特定分析错误详细信息并适当地修改源文件. 分析器错误消息: 未能加载类型“ ...
- 将Python当作计算器
在交互模式中,最近一个表达式的值赋给变量 _.这样我们就可以把它当作一个桌面计算器,很方便的用于连续计算.例如: >>> price = 1.25 #声明变量price >&g ...
- URL重定向漏洞,python打造URL重定向漏洞检测脚本
前言: 今天学习了重定向漏洞,这个漏洞比较好理解 漏洞名:URL重定向漏洞 威胁:低 漏洞的来源:开发者对head头做好对应的过滤和限制 例子: 有漏洞的网站:http://a.com/x.php?u ...
- 一些有用的Java参考资料
Better Java,一些好的Java实践 Google Java Style Guide 30个Java编程技巧 JDK8新增语法特性简介,对Java8中新增的函数接口.Lambda表达式.方法引 ...
- 《读书报告 -- Elasticsearch入门 》--简单使用(2)
<读书报告 – Elasticsearch入门 > ' 第四章 分布式文件存储 这章的主要内容是理解数据如何在分布式系统中存储. 4.1 路由文档到分片 创建一个新文档时,它是如何确定应该 ...
- Linux测量kernel子模块加载时间的方法
1. 在文件kernel/init/main.c里面,在接口do_one_initcall( )中,将initcall_debug设置为true,然后编译boot.img 2. 使用adb shell ...
- Swift完成fizz buzz test
看到一篇文章上说,很多貌似看过很多本编程书的童鞋连简单的fizz buzz测试都完不成. 不知道fizz buzz test为何物的,建议自行搜之. 测试要求是,编写满足以下条件的代码: Write ...
- Swift中关于任意类型的数组
在Objc中你是不可以把一个非对象类型放入数组的,你必须将其"封箱",然后再放入数组. 在Swift中你可将非对象类型轻松放入数组: let ary = [1,2,3] 你可以明确 ...
- 剑指Offer——知识点储备-常用算法
剑指Offer--知识点储备-常用算法 快速排序 注:若排序是有序的,采用快排,则退化为冒泡排序. 解决这个问题,采用两个选取基准的方法 (1)随机选取基数(在这个区间内随机取一个数) 出现的恶劣情况 ...
- Appium移动自动化测试(五)--app控件获取之uiautomatorviewer
初探 在Android的SDk提供了以下的工具来支持我们进行UI自动化测试: uiautomatorviewer:用来扫描和分析Android应用程序的UI控件的工具. uiautomator:一个包 ...