富文本编辑器UEditor

4次阅读

共计 20836 个字符,预计需要花费 53 分钟才能阅读完成。

富文本编辑器 -UEditor

1.spspring-boot 整合 ueditor

1.1.UEditor 简介

UEditor 由百度开发
官网 https://ueditor.baidu.com/web…
github https://github.com/fex-team/u…
官方文档 http://fex.baidu.com/ueditor/…

1.2. 下载

官网下载链接 https://ueditor.baidu.com/web…
笔者后端使用 JAVA, 所以下载 jsp 版本,UTF- 8 版

开发版下载地址
https://github.com/fex-team/u…

下载后目录结构

common-fileupload.jar 包存在 ddos 漏洞,请尽快升级到最新的版本,直达链接:Apache fileupload jar
https://commons.apache.org/pr…

1.3. 添加 UEDitor 依赖到本地 maven 库,

使用 eclipse 的 import
右击 ->Import->Install or deploy an aitifact to Maven repository-> 输入相关信息

生成的文件非常全

如果不添加, 需要将 jar 包放到 lib 下, 在 pom.xml 中引入如下
<dependency>
    <groupId>com.baidu.ueditor</groupId>
    <artifactId>ueditor</artifactId>
    <version>1.1.2</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/ueditor-1.1.2.jar</systemPath>
</dependency>

1.4.spring-boot 整合 Ueditor

创建 spring-boot 项目,pom.xml 文件如下

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.8.RELEASE</version>
</parent>
<packaging>jar</packaging>
<properties>
  <!-- 文件拷贝时的编码 -->
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <!-- 继承 spring-boot 时才有效 -->
  <java.version>1.8</java.version>
</properties>
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!-- tomcat 解析 jsp 依赖 -->
  <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
  </dependency>
</dependencies>
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <mainClass>com.Application</mainClass>
      </configuration>
    </plugin>
  </plugins>
</build>

添加依赖 ueditor 依赖

<dependency>
  <groupId>commons-codec</groupId>
  <artifactId>commons-codec</artifactId>
</dependency>
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.4</version>
</dependency>
<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.5</version>
</dependency>
<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
</dependency>
<dependency>
  <groupId>com.baidu.ueditor</groupId>
  <artifactId>ueditor</artifactId>
  <version>1.1.2</version>
</dependency>

将下载后的文件夹名为 ueditor-1.4 放到 webapps 下
在 ueditor-1.4 下编写 ueditor01.html 内容如下

<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<title></title>
</head>

<body>
<!-- 加载编辑器的容器 -->
<script id="container" name="content" type="text/plain">
  这里写你的初始化内容
</script>
<!-- 配置文件 -->
<script src="ueditor.config.js" type="text/javascript" charset="utf-8"></script>
<!-- 编辑器源码文件 -->
<script src="ueditor.all.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
<!-- 实例化编辑器 -->
var ue = UE.getEditor('container');
</script>
</body>

</html>

显示如下

一定要启动项后端目, 需要加载 controller.jsp 文件

不启动项目报错如如下


解决办法有 2 个, 如果不使用前后端分离, 要保证 jsp 有 controller.jsp 和 config.json

1.5. 前后端分离

前后端分离目的是为了删除 tomcat-embed-jasper 的依赖
编写 controller

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baidu.ueditor.ActionEnter;

@Controller
@RequestMapping("ueditor-1.4")
public class UeditorController {@RequestMapping("ueditor/controller")
  @ResponseBody
  public void getConfigInfo(HttpServletRequest request, HttpServletResponse response) {response.setContentType("application/json;charset=utf-8");
    String rootPath = request.getSession().getServletContext().getRealPath("/");
    try {String exec = new ActionEnter(request, rootPath).exec();
      PrintWriter writer = response.getWriter();
      writer.write(exec);
      writer.flush();
      writer.close();} catch (IOException e) {e.printStackTrace();
    }
  }
}

修改 editor.config.js

// 服务器统一请求接口路径
, serverUrl: URL +"ueditor/controller" /*"jsp/controller.jsp"*/

发送的参数

ueditor-1.4/ueditor/controller?action=config&&noCache=1591844726761

返回的参数

{state: 配置文件初始化失败}

分析源码

com.baidu.ueditor.ActionEnter.ActionEnter(HttpServletRequest, String)
public ActionEnter(HttpServletRequest request, String rootPath) {
   this.request = request;
   this.rootPath = rootPath;
   this.actionType = request.getParameter("action");
   this.contextPath = request.getContextPath();
   this.configManager = ConfigManager.getInstance(this.rootPath, this.contextPath, request.getRequestURI());
}

ConfigManager.getInstance

ConfigManager 的构造方法

initEnv 方法

看到了没有到 originalPapt 同级的文件夹下找 config.json
orginPath 的值如下

if (contextPath.length() > 0) {this.originalPath = this.rootPath + uri.substring(contextPath.length());
} else {this.originalPath = this.rootPath + uri;}

那么 rootPath 的是什么呢?

C:\Users\Administrator\AppData\Local\Temp\tomcat-docbase.3976607370684852948.11025\

uri 的值

/litongjava-spring-boot-ueditor/ueditor-1.4/ueditor/controller

contextPath 的值

/litongjava-spring-boot-ueditor

解决办法, 获取静态目录作为 rootPath, 将 config.json 放到静态目录的 ueditor-1.4/ueditor 下面
配置成功后返回的数据如下

{"videoMaxSize":102400000,"videoActionName":"uploadvideo","fileActionName":"uploadfile","fileManagerListPath":"/ueditor/jsp/upload/file/","imageCompressBorder":1600,"imageManagerAllowFiles":[".png",".jpg",".jpeg",".gif",".bmp"],"imageManagerListPath":"/ueditor/jsp/upload/image/","fileMaxSize":51200000,"fileManagerAllowFiles":[".png",".jpg",".jpeg",".gif",".bmp",".flv",".swf",".mkv",".avi",".rm",".rmvb",".mpeg",".mpg",".ogg",".ogv",".mov",".wmv",".mp4",".webm",".mp3",".wav",".mid",".rar",".zip",".tar",".gz",".7z",".bz2",".cab",".iso",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".pdf",".txt",".md",".xml"],"fileManagerActionName":"listfile","snapscreenInsertAlign":"none","scrawlActionName":"uploadscrawl","videoFieldName":"upfile","imageCompressEnable":true,"videoUrlPrefix":"","fileManagerUrlPrefix":"","catcherAllowFiles":[".png",".jpg",".jpeg",".gif",".bmp"],"imageManagerActionName":"listimage","snapscreenPathFormat":"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}","scrawlPathFormat":"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}","scrawlMaxSize":2048000,"imageInsertAlign":"none","catcherPathFormat":"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}","catcherMaxSize":2048000,"snapscreenUrlPrefix":"","imagePathFormat":"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}","imageManagerUrlPrefix":"","scrawlUrlPrefix":"","scrawlFieldName":"upfile","imageMaxSize":2048000,"imageAllowFiles":[".png",".jpg",".jpeg",".gif",".bmp"],"snapscreenActionName":"uploadimage","catcherActionName":"catchimage","fileFieldName":"upfile","fileUrlPrefix":"","imageManagerInsertAlign":"none","catcherLocalDomain":["127.0.0.1","localhost","img.baidu.com"],"filePathFormat":"/ueditor/jsp/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}","videoPathFormat":"/ueditor/jsp/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}","fileManagerListSize":20,"imageActionName":"uploadimage","imageFieldName":"upfile","imageUrlPrefix":"","scrawlInsertAlign":"none","fileAllowFiles":[".png",".jpg",".jpeg",".gif",".bmp",".flv",".swf",".mkv",".avi",".rm",".rmvb",".mpeg",".mpg",".ogg",".ogv",".mov",".wmv",".mp4",".webm",".mp3",".wav",".mid",".rar",".zip",".tar",".gz",".7z",".bz2",".cab",".iso",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".pdf",".txt",".md",".xml"],"catcherUrlPrefix":"","imageManagerListSize":20,"catcherFieldName":"source","videoAllowFiles":[".flv",".swf",".mkv",".avi",".rm",".rmvb",".mpeg",".mpg",".ogg",".ogv",".mov",".wmv",".mp4",".webm",".mp3",".wav",".mid"]}

1.6. 设置图片上传

笔者测试图片上传是出现问题如
请求

ueditor/controller?action=uploadimage&encode=utf-8

响应

{state: "未找到上传数据"}

上传源码分析

Uploader

BinaryUploader

那么 HttpServletRequest 到底有没有数据呢? 有数据代码也没有问题, 但是为什么就是不行呢?
原因:ueditor 自事的 fileupload 组件与 spring 的有冲突
解决办法, 使用 Servlet
编写 Servlet

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.baidu.ueditor.ActionEnter;
// 使用注解测试无效
//@WebServlet(name = "UEditorServlet", urlPatterns = "/UEditor")
public class UEditorServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");
    response.setHeader("Content-Type", "text/html");
    PrintWriter out = response.getWriter();
    ServletContext application = this.getServletContext();
    URL systemResource = ClassLoader.getSystemResource("");
    String rootPath = systemResource.getFile();
    //String rootPath = application.getRealPath("/");

    String action = request.getParameter("action");
    String result = new ActionEnter(request, rootPath).exec();
    if (action != null &&
      (action.equals("listfile") || action.equals("listimage"))) {rootPath = rootPath.replace("\\", "/");
      result = result.replaceAll(rootPath, "/");
    }
    out.write(result);
  }
}

  @Bean
  public ServletRegistrationBean servletRegistrationBean() {return new ServletRegistrationBean(new UEditorServlet(), "/ueditor-1.4/UEditor");
  }

config.json 路径:srcmainresourcesueditor-1.4config.json
测试上传文件的, 上传成功, 成功后的路径是 targetclassesueditorjspuploadimage20200615
访问路径是
默认的访问路径是 http://127.0.0.1/ueditor/jsp/…
修改 config.json 中的上传保存路径
将 /ueditor/jsp/upload 替换为 /litongjava-spring-boot-ueditor/ueditor/jsp/upload, 一种有 8 处

1.7. 配置参数

传入自定义的参数
编辑器有很多可自定义的参数项,在实例化的时候可以传入给编辑器:
var ue = UE.getEditor(‘container’, {

autoHeight: false

});
配置项也可以通过 ueditor.config.js 文件修改,具体的配置方法请看前端配置项说明 http://fex.baidu.com/ueditor/…

initialFrameHeight: window.screen.availHeight-300,

1.8. 设置和读取编辑器的内容

通 getContent 和 setContent 方法可以设置和读取编辑器的内容

// 对编辑器的操作最好在编辑器 ready 之后再做
ue.ready(function() {
    // 设置编辑器的内容
    ue.setContent('hello');
    // 获取 html 内容,返回: <p>hello</p>
    var html = ue.getContent();
    // 获取纯文本内容,返回: hello
    var txt = ue.getContentTxt();});

详细文档
UEditor 官网:http://ueditor.baidu.com
UEditor API 文档:http://ueditor.baidu.com/doc
UEditor Github 地址:http://github.com/fex-team/ue…

2. 使用 UEditor

2.1. 定制工具类图标

定制工具栏图标
UEditor 工具栏上的按钮列表可以自定义配置, 只需要通过修改配置项就可以实现需求

配置项修改说明
修改配置项的方法:
1. 方法一:修改 ueditor.config.js 里面的 toolbars
2. 方法二:实例化编辑器的时候传入 toolbars 参数
var ue = UE.getEditor(‘container'{toolbars:[]});
其他配置项:配置项说明
简单列表

toolbars: [['fullscreen', 'source', 'undo', 'redo', 'bold']
]

多行列表

toolbars: [['fullscreen', 'source', 'undo', 'redo'],
  ['bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc']
]

两行的例子: 自定义工具栏
工具栏按钮分割线
配置项里用竖线 ‘|’ 代表分割线

完整的按钮列表

toolbars: [
    [
        'anchor', // 锚点
        'undo', // 撤销
        'redo', // 重做
        'bold', // 加粗
        'indent', // 首行缩进
        'snapscreen', // 截图
        'italic', // 斜体
        'underline', // 下划线
        'strikethrough', // 删除线
        'subscript', // 下标
        'fontborder', // 字符边框
        'superscript', // 上标
        'formatmatch', // 格式刷
        'source', // 源代码
        'blockquote', // 引用
        'pasteplain', // 纯文本粘贴模式
        'selectall', // 全选
        'print', // 打印
        'preview', // 预览
        'horizontal', // 分隔线
        'removeformat', // 清除格式
        'time', // 时间
        'date', // 日期
        'unlink', // 取消链接
        'insertrow', // 前插入行
        'insertcol', // 前插入列
        'mergeright', // 右合并单元格
        'mergedown', // 下合并单元格
        'deleterow', // 删除行
        'deletecol', // 删除列
        'splittorows', // 拆分成行
        'splittocols', // 拆分成列
        'splittocells', // 完全拆分单元格
        'deletecaption', // 删除表格标题
        'inserttitle', // 插入标题
        'mergecells', // 合并多个单元格
        'deletetable', // 删除表格
        'cleardoc', // 清空文档
        'insertparagraphbeforetable', //"表格前插入行"
        'insertcode', // 代码语言
        'fontfamily', // 字体
        'fontsize', // 字号
        'paragraph', // 段落格式
        'simpleupload', // 单图上传
        'insertimage', // 多图上传
        'edittable', // 表格属性
        'edittd', // 单元格属性
        'link', // 超链接
        'emotion', // 表情
        'spechars', // 特殊字符
        'searchreplace', // 查询替换
        'map', //Baidu 地图
        'gmap', //Google 地图
        'insertvideo', // 视频
        'help', // 帮助
        'justifyleft', // 居左对齐
        'justifyright', // 居右对齐
        'justifycenter', // 居中对齐
        'justifyjustify', // 两端对齐
        'forecolor', // 字体颜色
        'backcolor', // 背景色
        'insertorderedlist', // 有序列表
        'insertunorderedlist', // 无序列表
        'fullscreen', // 全屏
        'directionalityltr', // 从左向右输入
        'directionalityrtl', // 从右向左输入
        'rowspacingtop', // 段前距
        'rowspacingbottom', // 段后距
        'pagebreak', // 分页
        'insertframe', // 插入 Iframe
        'imagenone', // 默认
        'imageleft', // 左浮动
        'imageright', // 右浮动
        'attachment', // 附件
        'imagecenter', // 居中
        'wordimage', // 图片转存
        'lineheight', // 行间距
        'edittip', // 编辑提示
        'customstyle', // 自定义标题
        'autotypeset', // 自动排版
        'webapp', // 百度应用
        'touppercase', // 字母大写
        'tolowercase', // 字母小写
        'background', // 背景
        'template', // 模板
        'scrawl', // 涂鸦
        'music', // 音乐
        'inserttable', // 插入表格
        'drafts', // 从草稿箱加载
        'charts', // 图表
    ]
]

2.2. 前端配置项说明

实例化时设置配置项

var ue = UE.getEditor('container', {
    toolbars: [['fullscreen', 'source', 'undo', 'redo', 'bold']
    ],
    autoHeightEnabled: true,
autoFloatEnabled: true
});

读取配置项
读取配置项可以通过 getOpt 方法读取

var lang = ue.getOpt('lang'); // 默认返回:zh-cn

前端配置项说明
UEDITOR_HOME_URL {Path String} [默认值:根据 config 文件路径自动获取] // 为编辑器实例添加一个路径,这个不能被注释, 笔者使用的值 http://localhost:8080/ueditor-1.4/

2.3. 目录说明

UEditor 下载包有两个类型: 源码包 和 部署包
源码包包含了 UEditor 的源码、各后台的代码和使用的例子

  1. 部署包目录说明

部署包解压后的文件目录结构如下所示
ueditor 解压后的目录列表
dialogs: 弹出对话框对应的资源和 JS 文件
lang: 编辑器国际化显示的文件
php 或 jsp 或 asp 或 net: 涉及到服务器端操作的后台文件
themes: 样式图片和样式文件
third-party: 第三方插件(包括代码高亮,源码编辑等组件)
ueditor.all.js: 开发版代码合并的结果, 目录下所有文件的打包文件
ueditor.all.min.js: ueditor.all.js 文件的压缩版,建议在正式部署时采用
ueditor.config.js: 编辑器的配置文件,建议和编辑器实例化页面置于同一目录
ueditor.parse.js: 编辑的内容显示页面引用,会自动加载表格、列表、代码高亮等样式, 具体看内容展示文档
ueditor.parse.min.js: ueditor.parse.js 文件的压缩版,建议在内容展示页正式部署时采用

  1. 源码包目录说明

源码包解压后的文件目录结构如下所示
ueditor 解压后的目录列表
源码包部分目录和文件与部署包名称一致, 用途也会是一致, 具体说明如下:
_doc: 部分 markdown 格式的文档
_example: ueditor 的使用例子
_parse: ueditor.parse.js 的源码,parse 的用途具体看内容展示文档
_src: ueditor.all.js 的源码, 打包方法看 grunt 打包文档
_srccore: ueditor 核心代码
_srcplugins: 插件文件
_srcui: ui 相关文件
_srcadapter: 桥接层文件, 对接 ueditor 核心和 ui 代码
php: php 后台文件的目录
phpconfig.json: 后端配置文件, 所有前后端相关配置项, 都放在这里
phpcontroller.php: 接收所有请求的接口文件, 通过它判断 action 参数, 分发具体任务给其他 php 文件
phpaction_crawler: 撞去远程文件的代码, 转存文件使用
phpaction_upload: 上传图片、附件、视频的处理代码
phpaction_list: 列出在线的图片或者是附件
phpUpload.class.php: 上传文件使用的类
jsp: jsp 后台文件的目录
jspconfig.json: 后端配置文件, 所有前后端相关配置项, 都放在这里
jspcontrooler.jsp: 接收所有请求的接口文件
jsplib: 所有用到的 jar 包, 其中的 ueditor-*.jar 包是 ueditor 所有后台相关处理逻辑的工具
jspsrc: lib 里面的 uedior-*jar 文件的 java 源码
asp: asp 后台文件的目录
net: .net 后台文件的目录
App_Code: 上的文件是应用程序的源码。
Bin: 里面的是应用程序的依赖库,当前依赖 Newtonsoft 的 Json 库。Bin 目录和 App_Code 目录受应用程序保护,不用担心被用户访问到。
config.json: 是 UEditor 后端的配置文件,上一节已经介绍了比较重要的配置项。
controller.ashx: 是 UEditor 请求的入口,它把不同的 action 分发到不同的 Handler 来处理。
net.sln: 是项目的解决方案文件,安装 Visual Studio 2013 或以上的机器可以打开进行项目的改造。
README.md: 是 net 后台使用文件。
Web.config: 是应用程序的配置文件
dialogs: 同部署包说明
lang: 同部署包说明
themes: 同部署包说明
third-party: 同部署包说明
changelog.md: 各版本的 ueditor 更新记录
Gruntfile.js: grunt 执行的任务文件, 用来把源码包打包成部署版本, 打包方法看 grunt 打包文档
LICENSE: 开源协议说明证书,ueditor 使用 MIT 开源协议
ueditor.config.js: 前端配置文件
ueditor.parse.js: 还没合并时使用的 parse 文件, 会自动加载_parse 里面的文件

2.4. 提交表单

1. 按照部署编辑器的教程,完成编辑器加载
2. 把容器放到 form 表单里面,设置好要提交的路径,如下面代码中的 <form> 标签
3. 在 script 中添加一个 name 值

<body>
  <form action="server.php" method="post">
    <!-- 加载编辑器的容器 -->
    <script id="container" name="content" type="text/plain">
      这里写你的初始化内容
    </script>
  </form>
  <!-- 配置文件 -->
  <script type="text/javascript" src="ueditor.config.js"></script>
  <!-- 编辑器源码文件 -->
  <script type="text/javascript" src="ueditor.all.js"></script>
  <!-- 实例化编辑器 -->
  <script type="text/javascript">
    var editor = UE.getEditor('container');
  </script>
</body>

2.5. 编辑内容展示

大家使用 UEditor 是为了让用户能在页面中编辑富文本内容,但这应该只是手段方法。我们最终的目的是为了呈现用户编辑的内容。也就是内容的展示。原来我们对这块是不考虑的,只关注在编辑端。但随着编辑器产出内容的增加和复杂化,比如图表展示,代码高亮,自定义的列表标号等等,如果都在最终产出的编辑数据中处理,那势必会导致产出数据带有冗余内容,而且也很大程度上硬编码了展示时定制效果。基于这些问题,uparse 产生了。

1. 在下载包中找到 ueditor.parse.js
2. 根据你的路径加载 uparse.js

<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <script src="../ueditor.parse.js"></script>
    <title></title>
</head>

将 uparse.js 记载到页面,不同目录结构,路径不同.
当加载了 uparse.js 后,就可以调用 uParse 这个函数,执行内容解析了。

//uParse 的语法
uParse(cssSelector,[options])
cssSelector,是告诉 uParse 你将编辑数据放到那个容器里了,比如你放到一个 div 里
<div id="content">
  <p>dsfsdF</p>
  <p>sdsdf</p>
</div>

cssSelector 就是 #content, 现在支持 3 种格式,tag,id,class. 也就是你可以渲染页面中多个地方。options 是个 json 对象。基于 1.3.5 版本,可配置的参数。

{
    rootPath: '', //ueditor 所在的路径,这个要给出,让 uparse 能找到 third-party 目录
    // 因为需要引入目录下的那些 js 文件,当然会根据你的编辑数据,按需加载
    liiconpath: 'http://bs.baidu.com/listicon/', // 自定义列表标号图片的地址,默认是这个地址
    listDefaultPaddingLeft: '20' // 自定义列表标号与文字的横向间距
}

一般只要给个 rootPath 就够了,其他的都可以使用默认值。一般在页面底部加入如下代码

uParse('.content', {rootPath: '../'})

这个表示对于 className 是 content 的容器里边的内容进行解析。
完整 js 如下

<head>
<meta charset="UTF-8">
<title></title>
<script src="ueditor-1.4/ueditor.parse.js" type="text/javascript" charset="utf-8"></script>
</head>

<body>
<div id="content">
    <p> 我是李通 </p>
    <p> 我是一个 90 后程序员 </p>
</div>
<script type="text/javascript">
uParse('content', {rootPaht: './ueditor-1.4'})
</script>
</body>

显示如下

生产环境中肯定是从后端获取内容添加 div 中进行展示

3.ueditor 使用案例

3.1. 收集用户不满意的原因

界面内容如下

<!DOCTYPE html>
<html>
<!--
    作者:litongjava@qq.com
    时间:2019-02-21
    描述:收集用户的不满意原因
-->

<head>
<meta charset="UTF-8">
<!-- 编辑器默认配置文件 -->
<script src="../ueditor-1.4/ueditor.config.js" type="text/javascript" charset="utf-8"></script>
<!-- 编辑器源码文件 -->
<script src="../ueditor-1.4/ueditor.all.js" type="text/javascript" charset="utf-8"></script>
<!--jquery-->
<script src="../js/jquery-1.9.1.min.js" type="text/javascript" charset="utf-8"></script>
<!-- 工程变量 -->
<script src="../js/project.js" type="text/javascript" charset="utf-8"></script>
<!--base64 client-->
<script src="../js/base64Client.js" type="text/javascript" charset="utf-8"></script>
<!--ajax-->
<script src="../js/ajax.js" type="text/javascript" charset="utf-8"></script>
<!-- 邮箱提示 -->
<script src="../js/autofillmail.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" href="../layui/css/layui.css" media="all" />
<style>
* {
    font-family: "微软雅黑";
    margin: 0;
    padding: 0;
}

ul,
li {list-style: none;}

.inputElem {
    height: 22px;
    line-height: 22px;
    border: 1px solid #ff4455;
}

.auto-tip li {
    width: 100%;
    height: 30px;
    line-height: 30px;
    font-size: 16px;
    background: #eee;
}

.auto-tip li.hoverBg {
    background: #ddd;
    cursor: pointer;
}

.auto-tip li .em {color: #FF0000;}

.red {color: #000000;}

.hidden {display: none;}

form {padding: 15px;}
</style>
<script type="text/javascript">
window.onload = function() {
    // 初始化提示插件
    new EmailAutoComplete({
        parentCls: '.parentemail', // 当前 input 元素的父级类
        targetCls: '.email', // 目标 input 元素
    });
}
</script>
</head>

<body>
<form class="layui-form" action="reason" method="post">
    <input type="hidden" name="sessionid" />
    <div class="layui-form-item">
        <label class="layui-form-label"> 邮箱 </label>
        <div class="layui-input-block">
            <div class="parentemail">
                <input type="text" name="email" lay-verify="title" autocomplete="off" placeholder="请输入邮箱" class="layui-input email">
            </div>
        </div>
    </div>
    <div class="layui-form-item" id="phone">
        <label class="layui-form-label"> 手机号 </label>
        <div class="layui-input-block">
            <input type="text" name="phone" lay-verify="title" autocomplete="off" placeholder="请输入手机号" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label"> 用户问题 </label>
        <div class="layui-input-block">
            <input type="text" name="userQuestion" lay-verify="title" autocomplete="off" placeholder="请输入标题" class="layui-input" readonly="readonly">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label"> 标准问题 </label>
        <div class="layui-input-block">
            <input type="text" name="question" lay-verify="title" autocomplete="off" placeholder="请输入标题" class="layui-input" readonly="readonly">
        </div>
    </div>
    <div class="layui-form-item layui-form-text">
        <label class="layui-form-label"> 答案 </label>
        <div class="layui-input-block">
            <textarea placeholder="请输入内容" name="answer" class="layui-textarea" readonly="readonly"></textarea>
        </div>
    </div>
    <div class="layui-form-item layui-form-text">
        <label class="layui-form-label"> 原因 </label>
        <div class="layui-input-block">
            <script id="container" name="reason" type="text/plain"></script>
        </div>
    </div>
    <div class="layui-form-item">
        <div class="layui-input-block">
            <button class="layui-btn" lay-submit=""lay-filter="demo1"> 立即提交 </button>
        </div>
    </div>
</form>
</body>
<script src="../layui/layui.all.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function() {layui.form.render();
})
UE.Editor.prototype.placeholder = function(justPlainText) {
    var _editor = this;
    _editor.addListener("focus", function() {var localHtml = _editor.getPlainTxt();
        if($.trim(localHtml) === $.trim(justPlainText)) {_editor.setContent(" ");
        }
    });
    _editor.addListener("blur", function() {var localHtml = _editor.getContent();
        if(!localHtml) {_editor.setContent(justPlainText);
        }
    });
    _editor.ready(function() {_editor.fireEvent("blur");
    });
};
var ue = UE.getEditor('container');
ue.placeholder("请输入你不满意的原因");
var msg = getQueryVariable("msg");
fill(msg);
var sessionid = getQueryVariable("sessionid");
if(project.dev()) {console.log("sessionid=" + sessionid);
}
document.getElementsByName("sessionid")[0].value = sessionid;

/**
 * 获取 http 请求参数
 * @param {Object} variable
 */
function getQueryVariable(variable) {var query = window.location.search.substring(1);
    var vars = query.split("&");
    for(var i = 0; i < vars.length; i++) {var pair = vars[i].split("=");
        if(pair[0] == variable) { //base64 编码之后包含 == 号
            var retval = "";
            for(var j = 1; j < pair.length; j++) {retval += pair[j];
            }
            retval = decodeURIComponent(retval); // 进行 URL 解码
            return retval;
        }
    }
    return(false);
}
/**
 * 填充问题和答案
 * @param {Object} msg
 */
function fill(msg) {if(!msg) {return false;}
    var array = msg.split(' '); //split char space
    var userQuestionBase64 = array[2];
    var questionBase64 = array[3];
    var answerBase64 = array[4];
    if(project.dev()) {console.log("user question:" + userQuestionBase64);
        console.log("question:" + questionBase64);
        console.log("answer:" + answerBase64);
    }

    base64Client.decode(userQuestionBase64, 'GBK', function(text) {document.getElementsByName("userQuestion")[0].value = text;
    });

    base64Client.decode(questionBase64, 'GBK', function(text) {document.getElementsByName("question")[0].value = text;
    });

    base64Client.decode(answerBase64, 'GBK', function(text) {document.getElementsByName("answer")[0].value = text;
    });
}
$(function() {var uri = ajax.getRootName() + "/config/getProjectVariable?key=project.collect.phone";
    ajax.get(uri, function(data) {if(data === 'false') {$("#phone").hide();}
    });
})
正文完
 0