百度编辑器UEditor使用问题小结

一、简介

百度UEditor编辑器是一款开源(也存在一些小问题)的很实用的超文本编辑器,由于其功能多,强大API支持,得到广泛的使用。很适合自定义编辑功能。

界面:

由于业务需要,要求在知识管理页面的文档编辑器换用百度UEditor,以支持更多的编辑功能。

二、引入UEditor编辑器:

  1. 百度编辑器官网http://ueditor.baidu.com/website/download.html#ueditor下载源码(支持多种语言的);
  2. 解压后直接将ueditor文件夹拷贝到自己的工程中:
  3. 引入依赖包:直接将ueditor/jsp/lib下自带的五个核心jar包,引入自己的工程中即可。
  4. 千万注意:引入jar包时避免这五个核心jar包冲突(在pom.xml或project structure/Libraries中查看,jar包是否冲突)

 

若项目是由Maven 来管理jar包的,最好通过在 pom.xml 中引入

报500错误:ueditor/jsp/controller.jsp 无法显示,就是由于jar包冲突问题;也会导致图片无法上传,提示“后端配置项没有正常加载,上传插件不能正常使用!”。

三、实例化编辑器前必须引入依赖:

  1. 配置文件
    <!-- 配置文件 -->
    <script type="text/javascript" charset="utf-8">
        window.UEDITOR_HOME_URL = "<PF:basePath/>view/ueditor/"; //UEDITOR_HOME_URL、config、all这三个顺序不能改变
    </script>
    <script type="text/javascript" charset="utf-8"    src="<PF:basePath/>view/ueditor/ueditor.config.js"></script>
    <script type="text/javascript" charset="utf-8"
        src="<PF:basePath/>view/ueditor/ueditor.all.js"></script>
    <script type="text/javascript" charset="utf-8" src="<PF:basePath/>view/ueditor/lang/zh-cn/zh-cn.js"></script>

    注意:

    UEDITOR_HOME_URL  是ueditor包存放的路径。也可以在ueditor.config.js中配置:

    //  为编辑器实例添加一个路径,这个不能被注释
    UEDITOR_HOME_URL: URL

  2. 实例化UEditor:

<script>
  
/*实例化UEditor*/
  
var editor;
   var
content;
  
$(function() {
      editor = UE.getEditor('container', {
        
toolbars: [
            [
'fullscreen', 'imageright', 'imagecenter', '|',
              
'simpleupload', 'insertimage', 'emotion', 'pagebreak', 'template', '|', 'horizontal'] ],
        
enableAutoSave: true   //启用自动保存
     
})
      editor.
ready(function() {
         content =
$("#contentIdHidden").html();
         if
(content != null){
           
UE.getEditor('container').setContent(content, true);
        
}
        
$('#completebtn').bind('click', function() { $('#contentId').val(UE.getEditor('container').getContent());       $('#contentIdHidden').html(UE.getEditor('container').getContent());

注意:

   2.1、toolbars:[[]] 此处内层中括号[]有N对,工具栏就可以分N行展示,”|”竖线是用于分隔不同类工具标签的作用,原样展示。

   2.2、当编辑器render渲染后执行的方法,监听ready事件接口,ready是编辑器进行一些前期的准备工作,大多数实例接口都应该放在该方法中,确保编辑器准备完成才能执行。

   2.3、setContent()方法是给编辑器设置内容,第二个参数为true时,不清空原来数据,在最后添加,为false时清空内容再插入内容。

3. 遇到前台无法显示编辑器:

  3.1、因为web.xml中配置*.html请求被拦截,(*.jsp , *.action , *.do 区别了解下),所以只能将ueditor文件下有关的html文件都改成jsp文件(个人项目不同);

  3.2、jar包冲突(com.baidu.ueditor-1.1.2-edit-1.0.jar 包 和 ueditor-1.1.2.jar 包冲突,解决办法,UEditor需要的五个jar包只从下载的UEditor解压包lib中拷贝,不要自己另外导入)

4. 图片上传路径配置:config.json

"imageUrlPrefix": "", /* 图片访问路径前缀 */

"imagePathFormat": "ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */

imageUrlPrefix如果只有一台主机,不需要跨域获取图片就没有必要配置,配空就行;

imagePathFormat一般都会自定义图片上传路径;

5. 自定义多图上传窗口功能:

<div id="tabhead" class="tabhead">
    <%--<span class="tab" data-content-id="remote"><var id="lang_tab_remote"></var></span>--%>
    <span class="tab focus" data-content-id="upload"><var id="lang_tab_upload"></var></span>
    <%--<span class="tab" data-content-id="online"><var id="lang_tab_online"></var></span>
    <span class="tab" data-content-id="search"><var id="lang_tab_search"></var></span>--%>
</div>

需求:

只保留了本地图片上传按钮;

ueditor\dialogs\image\image.html

如上注释代码隐藏插入图片、在线管理、图片搜索按钮:

6. 上传图片时,点击多图上传,上传弹框被遮盖了,是由于 UEditor 默认配置中 ueditor.all.js 文件中堆叠zIndex 顺序为999,导致知识编辑界面将图片上传弹框覆盖了,所以将UE.Editor.defaultOptions方法中 zIndex 改为 9999 完美解决。

7. 上传图片

  7.1. 自定义图片上传方法PuploadImg必须重写UE.Editor.prototype.getActionUrl()

很重要!很重要!很重要!

<script>
   /*重写 getActionUrl,自定义图片上传、保存接口,以js 的方式在配置文件ueditor.all.js、ueditor.config.js之后引入*/
    UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
    UE.Editor.prototype.getActionUrl = function(action) {
        if (action == 'uploadscrawl'|| action == 'uploadimage' || action == 'uploadfile') {
            return "<PF:basePath/>actionImg/PuploadImg.do";
        }else {
            return this._bkGetActionUrl.call(this, action);
        }
    }
</script>

    7.2. action=”uploadimge”对应config.json配置文件中上传图片配置的imageActionName参数,后端上传方法PuploadImg (@RequestParam(value=”upfile”,require=false) MultipartFile file)中upfile 对应config.json配置文件中的imageFiledName

8. 从其他站点复制图片到编辑器内容:远程抓取图片

  8.1. 配置:

//设置远程图片是否抓取到本地保存 catchRemoteImageEnable: true //设置是否抓取远程图片
在config.json中自定上传路径:
/* 上传保存路径,可以自定义保存路径和文件名格式 */
"catcherPathFormat": "actionImg/PubFUEditorLoadRemoteImg.do",

  8.2. 编辑器页面远程抓取图片处理方法

在ueditor.all.js文件中修改远程抓取图片处理方法:

catcherPathFormat = me.getOpt('catcherPathFormat');  // 获取自定义保存路径

function catchremoteimage(imgs, callbacks) {

    ...

    opt[catcherFieldName] = imgs;

    ajax.request(catcherPathFormat, opt);

}

ueditor.all.js远程抓取方法UE.plugins['catchremoteimage']中在获取远程图片链接时是抓取编辑页面中所有的img属性:

var src = ci.getAttribute("_src") || ci.src || "";

if (/^(https?|ftp):/i.test(src) && !test(src, catcherLocalDomain)) {

    remoteImages.push(src);

}

获取remoteImage时路径做了初步过滤处理,想自定义过滤抓取,可在config.json中配置:

"catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"]

  8.3. 后端远程图片本地化接口方法

在编辑器页面DocTUEditor.jsp文件中加入远程抓取图片后端处理接口方法:

UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
UE.Editor.prototype.getActionUrl = function(action) {
    if (action == 'uploadscrawl' || action == 'uploadimage' || action == 'uploadfile') {
        return "<PF:basePath/>actionImg/PubFUEditorPuploadImg.do";
    }else if(action == 'catchimage'){
        // 抓取远程图片处理
        return "<PF:basePath/>actionImg/ueditorPuploadImg.do";
    }else {
        return this._bkGetActionUrl.call(this, action);
    }
}

注意:

请求参数是资源路径数组(后端处理接口中接入参数String[] source,对应config.jsoncatchFiledName参数),将远程图片本地化,再上传,自定义回显路径。

后端处理接口:

@RequestMapping(value = "/ueditorPuploadImg.do")
@ResponseBody
public Map<String, Object> ueditorPuploadImg(String[] source,HttpServletRequest request,HttpSession session) {
     String[] sources = request.getParameterValues("source[]");
     for(String imgSource : sources){
          URL fileurl = new URL(imgSource);
          HttpURLConnection httpUrl = (HttpURLConnection) fileurl.openConnection();
          httpUrl.setRequestMethod("GET");
          httpUrl.setConnectTimeout(6 * 1000);
          httpUrl.connect();
          // 通过输入流获取图片数据
          InputStream inStream = httpUrl.getInputStream();

9. 从word文档中拷贝内容(主要是内容中的图片转存到UEditor编辑器中):

ueditor.config.js配置文件中默认情况下 ueditor 开启了 XSS 过滤(过滤、输入过滤、输出过滤都有相应的配置开关),任何不在 whitList 白名单上的标签及属性都会在转换时丢失。

这就直接导致了一些需要使用特殊标签或属性的功能直接失效,比如插入音乐、插入锚点、图片转存等。

一种方法就是关闭 XSS 过滤,可以注释掉上述配置或将上述三项设为 false;另一种方案就是将需要的标签及属性添加到白名单。

--- 插入锚点需要给 a 标签添加 name 属性,给 img 标签添加 anchorname 属性

--- 图片转存需要给 img 标签添加 word_imgstyle 属性

从word中拷贝图片后图片显示:

然后点击工具栏,拷贝图片本地地址,选中指定图片上传;

10. 编辑器导航栏固定:

ueditor编辑器工具栏默认是随窗口自动长高的,编辑框内容过长,工具栏就会被隐藏,不利于操作:

解决办法:在编辑器初始化时设置参数autoHeightEnabled为false

// 是否自动长高,默认true(false:自动添加滚动条,工具导航栏位置固定)
autoHeightEnabled: false

11. 预览页面图片显示问题:

由于项目中图片附件等采用的是相对路径,预览页面preview,是直接取的编辑器内容用于展示,所以必须将图片地址挑出来重新拼接完整地址,所以需要对图片附件等路径充完整。

12. 一个页面多个ueditor实例:

之前是一个页面一个编辑器ueditor实例,点击按钮进入编辑器页面,现在需要添加多个编辑器。

为了避免多个编辑器间干扰(第一个实例化的ueditor没有销毁,会影响到第二个编辑器的实例化),肯定是要在实例化ueditor时分配不同的ueditor ID,网上搜索一堆仅仅说了分配不同ID 就ok了,

问题一:但是分配了不同ID,后要么是控制台报错,要么是第一个编辑器可以正常使用,但第二个编辑器内容无法显示,或者显示的内容时第一个编辑器的内容造成冲突;

问题二:冲突问题。有网友给出了

方案1:在每次使用完编辑器后手动销毁ueditor实例(UE.delEditor()或ueditor.destroy()),但是也存在一个问题就是部分浏览器不支持:Uncaught TypeError: Cannot read property 'nodeType' of undefined

方案1:改写uediotr.all.js中的实例化方法,默认是先从instances[id]中获取,没有再实例化:

UE.getEditor = function (id, opt) {
    // 实例化前先销毁实例
    UE.delEditor(id);
    var editor = new UE.ui.Editor(opt);
    editor.render(id);
    return editor;
};

这个方案确实解决了冲突问题,但又带来了另外一个问题

当编辑完成退出该编辑器后,但没有保存,想再次进入继续编辑,可想而知会重新实例化一个ueditor,而此时编辑器中的内容也会被初始化,第一次进入编辑的内容被覆盖,所以这个方法不适合我的需求。

所以要求不销毁已经实例化的编辑器达到复用,但又不能冲突:

方案一:考虑共用一个uediotr页面,根据操作类型了区分自定义功能:

if('${editorType}' === '0'){
    // 知识编辑
    options = {
        toolbars: [ ['fullscreen', 'source']]
    }
}else if('${editorType}' === '1'){
    // 批注编辑
    options = {
        toolbars: [ ['undo', 'redo', '|','bold', 'italic']]
    }
}
editor = new UE.ui.Editor(options);
editor.render('container');
editor.ready(function() {
if('${editorType}' === '0'){
        content = $("#contentId").html();
    }else if('${editorType}' === '1'){
        // 指定编辑器限制字数
        editor.setOpt({
            maximumWords:1000
        });
        content = $("#commentId").html();
    }
    if(content != null){
        editor.setContent(content, true);
    }
注意:
这种方案存在一个问题,也是公用ueditor ID,导致内容冲突

方案二:两个ueditor页面,分别实例化。

这两中方案也存在一个问题,第二个(后点击后实例化的)ueditor编辑器无法显示,有网友提示退出编辑器时将文本域areatext 移除:

$('#container').remove();

而且是完全不影响未保存的重复编辑,不会导致覆盖问题。亲测可行。

13. 自定义标签:一键清除格式

   13.1、实例化编辑器时在toolbars数组新增一个“myone”自定义标签名

   13.2、找到ueditor.all.js文件中的btnCmds数组,在其中新增一个“myone”字符串;

   13.3、添加图标one.pngimages图片文件中;

   13.4、为自定义标签添加样式;

     /*自定义标签*/

     .edui-default .edui-toolbar .edui-for-myone .edui-icon {

          background-position: -89px 3;

          background-image: url("../images/one.png");

      }

   13.5、在ueditor.all.js文件中仿照其他标签实现自定义标签按钮功能:

      UE.plugins[' myone'] = function(){}

 

第一次写博客,这个编辑器也是很难用 ^_^!!,写的很简单

希望对遇到同样问题的朋友一些提示作用

不足之处欢迎指正交流

感谢众多大神的提示,文章链接已经找不到,无法贴出来,抱歉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值