最近对电商项目系统优化遇到个棘手的需求:需要将以前的一整个富文本进一步拆分,搞成多个模块的富文本。其中有一个行程安排功能,给行程每一天安排目的地、景点、饮食等,需要单独设置每一天行程的富文本。我实现的大致步骤是通过修改行程天数的时候,就会动态的添加、删除对应天的富文本。
实现效果如此:
踩坑过程:
首先参照以前的项目代码,可以看到是通过如下方式创建富文本。
<textarea id="attention" name="attention" ></textarea>
<script>
var contentUEditor2= UE.getEditor('attention'); //初始化编辑器
</script>
然后就尝试着弄,添加编辑器没问题,但是却没法删除。然后想着通过数组存放编辑器,行程天数修改时,增加、删除数组中的编辑器,从而实现动态添加编辑器功能。然而,通过此种方式,也无法销毁对应的编辑器,console老是显示报错。
后来看到一篇博客《JQuery 动态添加多个编辑器,ueditor等其他编辑器同样适用》,找到了对应的实现方法。文中是通过如下方式创建富文本编辑器的。
<script id="editor_0" type="text/plain" style="width:1024px;height:100px;"></script>
<script>
UE.getEditor(`editor_0`); //初始化编辑器
</script>
此种方式,可以很灵活的操作编辑器。 通过将编辑器的id存放在数组中,修改行程天数时,如果天数减少,就通过数组中的id找到编辑器,删除编辑器;天数增加,就追加编辑器,并把id放入数组中。
实现思想:
通过行程天数,动态增加、删除天数。初次加载时,从系统处拿到行程天数day(或新建时默认的天数),然后动态创建day个script元素,将编辑器id依次存入数组arr中;然后页面加载完后,编辑数组初始化day个编辑器,并将富文本信息填充加载进去;修改行程天数时,比如增加行程天数,先创建增加的天数的script元素,然后将id加入数组arr中,再初始化新加入的编辑器;减少行程天数的话,需要通过数组arr找到id对应的编辑器,然后销毁编辑器,再移除script元素。保存富文本时,此时form标签里面通过script元素生成的每个编辑器的name都是editorValue,但可以遍历编辑器,通过编辑器的getContent方法取出内含的富文本信息,进一步处理(转换成一个数组或其他处理)然后提交到服务器。
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<title>demo</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<!-- 引用的外部文件 -->
<script src="http://apps.bdimg.com/libs/ueditor/1.4.3.1/ueditor.config.js" type="text/javascript"></script>
<script src="http://apps.bdimg.com/libs/ueditor/1.4.3.1/ueditor.all.min.js" type="text/javascript"></script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<input name="number" value="2" type="number" min="1" onchange="changeNum()">
<br>
<br>
<table >
<tr class="datePlan">
<td colspan="3" style="text-align: center;">
<span style="font-family: 微软雅黑; font-size: 20px; color: rgb(247, 150, 70);">【行程安排】</span>
</td>
</tr>
</table>
<script type="text/javascript">
let arr = []; //存储当前已经存在的编辑器id的值,
/**
* 监听行程天数输入框。如果减少,则销毁arr后面多余的编辑器;如果增加,则末尾追加编辑器
*/
function changeNum(){
let day = $("input[name=number]").val();
if(day<1){
return;
}
debugger;
if(arr.length>day){
//减少日期的逻辑
let i = arr.length;
while(i>day){
//先销毁编辑器,然后再移除占用script元素
deleteEditor(i); //移除编辑器
$(".datePlanItem:last").remove(); //移除标题
$(".datePlanItem:last").remove();
arr.pop();
i--;
}
return;
}
//增加日期的逻辑
let i = arr.length+1;
let y = arr.length+1;
let html = "";
while(i<=day){
arr.push(i);
html += "<tr class='datePlanItem'>\n" +
"\t\t\t\t\t\t<td colspan='6' style='text-align: left'>\n" +
"\t\t\t\t\t\t\t<span style='font-family: 微软雅黑; font-size: 20px; color:#2D93CA; margin-left: 50px;'>Day"+i+"</span>\n" +
"\t\t\t\t\t\t</td>\n" +
"\t\t\t\t\t</tr>";
html += "<tr class='datePlanItem'><script id=\"date_plan"+i+"\" type=\"text/plain\" style=\"width:700px;height:150px;\"><\/script></tr>";
i++;
}
$(".datePlanItem:last").after(html); //追加script元素
while(y<=day){
initEditor(y,null); //初始化追加的编辑器
y++;
}
}
/**
* 页面初始化时,从后台拿到行程天数,然后自动创建对应天数的编辑器
*/
$(function() {
// let day = Number('${bean.day}'); //此处从后台拿到初始化的行程天数
let day = 2; //假设拿到的行程天数为2
day = day==0 ? 1 : day;
let i = 1;
let html = "";
while(i<=day){
arr.push(i);
html += "<tr class='datePlanItem'>\n" +
"\t\t\t\t\t\t<td colspan='6' style='text-align: left'>\n" +
"\t\t\t\t\t\t\t<span style='font-family: 微软雅黑; font-size: 20px; color:#2D93CA; margin-left: 50px;'>Day"+i+"</span>\n" +
"\t\t\t\t\t\t</td>\n" +
"\t\t\t\t\t</tr>";
html += "<tr class='datePlanItem'><script id=\"date_plan"+i+"\" type=\"text/plain\" style=\"width:700px;height:150px;\"><\/script></tr>";
i++;
}
$(".datePlan").after(html);
arr.forEach(i => {
initEditor(i,null);
})
});
/**
* 删除编辑器
* @param {Object} i 编辑器ID
*/
function deleteEditor(i) {
let ue = UE.getEditor(`date_plan${i}`);
ue.destroy();
}
/**
* 初始化编辑器函数
* @param {Object} i 编辑器ID
* @param {Object} content 编辑器富文本内容
*/
function initEditor(i,content) {
let ue = UE.getEditor(`date_plan${i}`);
//以下为给编辑器赋值
if(content != null && content.length != 0){
ue.addListener("ready", function () {
ue.setContent(content);
});
}
}
</script>
</body>
</html>
参考教程:
https://www.jianshu.com/p/2bae0c9cbe50