(微信编辑器)UEditor富文本嵌入135编辑器

UEditor简介

UEditor是由百度「FEX前端研发团队」开发的所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码。

本文以最新版本的1.4.3.3版本为教程来讲述

具体文档参见:http://fex.baidu.com/ueditor/

135编辑器简介

135编辑器是一款提供微信公众号文章排版和内容编辑的在线工具,样式丰富,支持秒刷、收藏样式和颜色、图片素材编辑、图片水印、一键排版等功能,轻松编辑微信公众号图文。他是一款基于UEditor富文本的编辑器,一共分为两种类型,一种是免费类型的嵌入型,也就是把135编辑器嵌入到UEditor富文本里面的菜单中,还有一种就是收费类型的无缝嵌入,这种会把135编辑器整体嵌入到个人或企业的内容编辑区域,在下图给大家看出来他们的区别。

免费版:

免费版

收费版:

收费版

使用优势

功能 UEditor 135编辑器
上传图片 需配置上传图片的选项 无需配置(上传的图片由135编辑器返回超链接,你无需配置)
上传视频 需配置上传视频的选项 无需配置(上传的视频由135编辑器返回超链接,你无需配置)
上传音乐 需配置上传音乐的选项 无需配置(上传的音乐由135编辑器返回超链接,你无需配置)
大多数功能 需配置大多数功能的选项 无需配置(大多数功能由135编辑器返回超链接,你无需配置)

安装UEditor

由于135编辑器是基于UEditor富文本的所以需要先安装UEditor富文本来支持135编辑器的嵌入,此方法只针对于免费使用135编辑器的人群,如果你是要付费使用的话你可以联系135编辑器的人,他们会有专门的技术人员提供技术支持。

下载UEditor编辑器

这里我是使用Flask来作为后端程序,如果你使用UEditor官网所指定的程序的话可以直接看UEditor的文档,访问UEditor首页,下载1.4.3.3 PHP UTF-8版本的UEditor,并解压到Flask应用程序的static目录。解压之后的目录结构是这样的:

|+static/
| |+ueditor/
| | |+dialogs/
| | |+lang/
| | |+php/ #因为我是Flask,所以这个目录中只有config.json对我有用,我已经把他放到了ueditor目录里面
| | |+themes/
| | |+third-party/
| | |-config.json
| | |-index.html
| | |-ueditor.all.js
| | |-ueditor.all.min.js
| | |-ueditor.config.js
| | |-ueditor.parse.js
| | |-ueditor.parse.min.js

+代表目录
-代表文件

在index.html中加入UEditor:

因为我是Flask程序,所以需要在templates目录中新建一个index.html的文件,你们可以根据自己语言和框架来选择文件建在那个目录中。

在index.html文件的head标签中加入下面几行:

<script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='ueditor/ueditor.config.js') }}"></script>
<script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='ueditor/ueditor.all.min.js') }}"> </script>
<!--建议手动加在语言,避免在ie下有时因为加载语言失败导致编辑器加载失败-->
<!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的中文,那最后就是中文-->
<script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='ueditor/lang/zh-cn/zh-cn.js') }}"></script>
<style>
    .edui-button.edui-for-135editor .edui-button-wrap .edui-button-body .edui-icon{
        background-image: url("http://static.135editor.com/img/icons/editor-135-icon.png") !important;
        background-size: 85%;
        background-position: center;
        background-repeat: no-repeat;
    }
    .edui-default{
        width: 920px;
        margin: 0 auto;
    }
</style>

在body标签加入:

<script id="editor" type="text/plain"></script>
<script type="text/javascript">
    //实例化编辑器
    //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例
    var ue = UE.getEditor('editor', {
        serverUrl: "/upload/"
    });
</script>

请求路径配置:

UEditor 1.4.2+ 起,推荐使用统一的请求路径,在部署好前端代码后,需要修改 ueditor.config.js 里的 serverUrl 参数(或者初始化时指定,见上面的代码),改成 ‘/upload/’ 。

UEditor初始化时,会向后端请求配置文件,后端收到请求后返回JSON格式的配置文件。具体实现参照后面的代码。

详细配置内容参见文档。

创建Flask应用程序(app.py):
# -*- coding: utf-8 -*-
 
from flask import Flask, render_template
 
app = Flask(__name__)
 
@app.route('/')
def index():
    return render_template('index.html')
 
@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    pass
 
if __name__ == '__main__':
    app.run(debug=True)

应用程序运行之后,我们访问 http://localhost:5000/ 就可以看到UEditor编辑器了,上图:
UEditor编辑器

UEditor后端请求规范说明

与后台通信的功能列表:
  • 上传图片
  • 拖放图片上传、粘贴板图片上传
  • word文档图片转存
  • 截图工具上传
  • 上传涂鸦
  • 上传视频
  • 上传附件
  • 在线图片管理
  • 粘贴转存远程图片
统一请求格式说明:
  • 前端请求通过唯一的后台文件 /upload/ 处理前端的请求
  • /upload/通过GET上的action参数,判断是什么类型的请求
  • 省去不必要的请求,去除涂鸦添加背景的请求,用前端FileReader读取本地图片代替
  • 请求返回数据的格式,常规返回json字符串,数据包含state属性(成功时返回’SUCCESS’,错误* 时返回错误信息)。
  • 请求支持jsonp请求格式,当请求有通过GET方式传callback的参数时,返回json数据前后加上括* 号,再在前面加上callback的值,格式类似这样:
    cb({“key”: “value”})

详细说明:http://fex-team.github.io/ueditor/#dev-request_specification

Flask实现后端请求

获取配置信息

由于接口升级,编辑器初始化时,首先会向后端请求配置信息,后端收到请求后,返
回相应的配置信息即可。

请求参数:
GET {"action": "config"}
POST "upfile": File Data
返回格式:
// 需要支持callback参数,返回jsonp格式
{
    "imageUrl": "http://localhost/ueditor/php/controller.php?action=uploadimage",
    "imagePath": "/ueditor/php/",
    "imageFieldName": "upfile",
    "imageMaxSize": 2048,
    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"]
}
主要功能代码:
@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    action = request.args.get('action')
 
    # 解析JSON格式的配置文件
    # 这里使用PHP版本自带的config.json文件
    with open(os.path.join(app.static_folder, 'ueditor', 'php','config.json')) as fp:
        try:
            # 删除 `/**/` 之间的注释
            CONFIG = json.loads(re.sub(r'\/\*.*\*\/', '', fp.read()))
        except:
            CONFIG = {}
 
    if action == 'config':
        # 初始化时,返回配置文件给客户端
        result = CONFIG
 
    return json.dumps(result)

这样的话就不会有什么问题出现了。

安装135编辑器

现在可以开始安装135编辑器了,因为笔者没有钱,所以使用的是免费版的135编辑器,所以他是嵌入在UEditor里面的,并且通过笔者不断观察135编辑器的网站和严格的一致性,导致笔者的UEditor和135编辑器的UEditor一模一样,在下面开始分享给大家。

安装插件

将插件的两个文件下载到项目ueditor对应的目录里,并将135editor.js加载到自己的网页中

http://www.135editor.com/js/ueditor/plugins/135editor.js
http://www.135editor.com/js/ueditor/dialogs/135editor/135EditorDialogPage.html

加载135editor.js

在index.html中的body标签中加入135editor.js文件

<script id="editor" type="text/plain"></script>
<script type="text/javascript" src="{{ url_for('static',filename='ueditor/plugins/135editor.js') }}"></script>
<script type="text/javascript">
    //实例化编辑器
    //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例
    var ue = UE.getEditor('editor', {
        serverUrl: "/upload/"
    });
</script>
重写themes目录下的iframe.css文件
@charset "utf-8";
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;line-height: 1.6;background: #FFF;height:100%;}
* {-webkit-max-logical-width: 100%;margin:0;padding:0;box-sizing: border-box!important;-webkit-box-sizing: border-box!important;}
body{-webkit-touch-callout:none;position: absolute; width: 100%;margin: 0;padding: 15px !important;font-size:16px;overflow-x:hidden;font-family:'微软雅黑','Microsoft YaHei',Arial,sans-serif;background-color:#FFF;line-height:inherit;height:100%;}
p{clear:both;margin:0 0;white-space: normal;}
img{*zoom:1;max-width:100%;*max-width:96%;height:auto !important;}
iframe{width:100% !important;border:0;background-color:inherit;}
.vote_area{display:block}
.vote_iframe{height:100%;width:100%!important;*width:96%!important}
.qqmusic_iframe{width:100%!important;height:75px;background-color:#fcfcfc;}
.audio_iframe{width:100%!important;background-color:#fcfcfc;height:82px}
.blockquote_iframe{width:100%!important;height:64px}
.blockquote_tips_iframe{width:100%!important;height:42px}
.video_iframe{background-color:#000;width:100%!important;*width:96%!important;position:static}
.shopcard_iframe{width:100%!important;height:95px;margin:14px 0}
.topic_iframe{width:100%!important;height:118px;margin:14px 0}
.weapp_app_iframe{height:330px;margin:14px 0}

body{cursor:text;}
a{color:#607fa6;text-decoration:none}
.guide{background-repeat:no-repeat;background-image: url(https://image.135editor.com/files/users/0/1/201708/xvCbQwOV_Ofmg.png);}
[contenteditable] {  caret-color: red;}
::-webkit-scrollbar {width:6px;height:6px;background: #f1f1f1;}
::-webkit-scrollbar-thumb {-webkit-box-shadow: inset 0 0 16px #c1c1c1;}
::-webkit-input-placeholder {color:    #ddd;}
* {
outline:0 none !important; blr:expression(this.onFocus=this.blur());
}
*:focus {
    outline: none !important;
}

li.placeholder {
    position: relative;list-style-type: none;
    margin: 0;
    padding: 0;
    border: none;
}
li.placeholder:before {
    position: absolute;
    content: " ";
    width: 0;
    height: 0;
    margin-top: -5px;
    left: 0px;
    top: -4px;
    border: 8px solid transparent;
    border-left-color: red;
    border-right: none;
}
.dragged {
    position: absolute !important;
    top: 0;
    opacity: 0.5;
    z-index: 2000;
}

.hiddenIn135{display:none !important;visibility: hidden !important;}.showIn135{display:initial !important;opacity: 1 !important;    visibility: visible !important;}
.hoverimg:hover{background:#000;}

blockquote{margin:0;padding-left:10px;border-left:3px solid #DBDBDB;}

ol,ul,dl
{
	/* IE7: reset rtl list margin. (#7334) */
	*margin-right: 0px;
	/* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/
	padding: 0 0 0 30px;
}

table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd;}
table{margin-bottom:10px;border-collapse:collapse;display:table;width:100%;margin:0 auto;}
td,th{word-wrap:break-word;word-break:break-all;padding:5px;border:1px solid #DDD}
caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center}
th{border-top:2px solid #BBB;background:#f7f7f7}
.ue-table-interlace-color-single{background-color:#fcfcfc}
.ue-table-interlace-color-double{background-color:#f7faff}
 td p{margin:0;padding:0;width:auto;height:auto;}

hr{border: 0px;border-top: 1px solid #ccc;}
img:hover {z-index:-1;cursor:pointer;}
pre{
	white-space: pre-wrap; /* CSS 2.1 */
	word-wrap: break-word; /* IE7 */
}
.marker {
	background-color: Yellow;
}

figure {
	text-align: center;
	border: solid 1px #ccc;
	border-radius: 2px;
	background: rgba(0,0,0,0.05);
	padding: 10px;
	margin: 10px 20px;
	display: inline-block;
}

figure > figcaption {
	text-align: center;
	display: block; /* For IE8 */
}
em{font-style: italic;}
.view{height:100%;position: relative !important;}
/*.view:after { content: ''; height: 60px; display: block;} */
._135editor {border:0 none;padding: 0px;z-index:0;position: relative !important;}
._135editor.active,.active{
    z-index: 100;
    outline: 1.5px dashed red !important;
    outline-offset: 2px;
}
._135editor .overActive{
    z-index: 100;
    outline: 1.5px dashed #6085ef !important;
    outline-offset: 2px;
}
._135editor .styleActive{
	z-index: 100;
    outline: 1.5px dashed #6085ef !important;
    outline-offset: 2px;
}
.mark-changed {
    z-index: 101;
    outline: 2px dashed darkturquoise !important;
    outline-offset: 2px;
}
/*._135editor.active:before{content: "";z-index: -1;display: block;position: absolute;box-sizing:border-box;width: 102%;left:-1%;height: 100%;border:1px dashed red;}
.view .active-135item:before {position: absolute;content: ''; left: 0;right: 0;top: 0;bottom: 0; box-sizing: border-box;border: 2px dashed red;margin:-5px;z-index: 1000;}*/
._135editor .draghandle{position: absolute;background-color:rgba(200,200,200,0.8);color:#333;cursor: move;top:-30px;right:-5px;padding: 3px 5px;font-size:12px;}
.view .active-135item{position: relative !important;}

h1,h2,h3,h4,h5,h6{font-weight:400;font-size:16px}
.hidden{display: none;visibility: hidden;}
.otf-poptools{ line-height: 24px; padding: 8px;
    border-radius: 0;border: 0 none;color: #FFF;position:absolute;width: 80%;left:15px;background:rgb(103,91,84);}
.otf-poptools span {
    cursor: pointer;
    margin: 0 5px;
}
.slider{height:16px!important;width:auto;position:relative;background-color:#FFF;margin-bottom:5px}
.slider .complete{height:100%;width:auto;color:#333;font-size:10px;line-height:16px;text-align:center;background-color:#ccc;z-index:2}
.slider .marker{height:16px;width:12px;cursor:pointer;position:absolute;top:0;left:0;background-color:#999;z-index:3}


/** 微信音乐,微信音频的样式 **/
.db {  display: block;}

qqmusic{
	min-height: 60px;
    width: 100%;
    background: #ccc;
    margin: 17px 1px 16px 0;
    display: block;
    opacity: 0.9;
    background-image: url('https://image.135editor.com/files/users/0/1/201611/Omfdq9uS_SNXj.png');
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
}
mpvoice{
    min-height: 90px;
    width: 100%;
    background: #ccc;
    margin: 17px 1px 16px 0;
    display: block;
    opacity: 0.9;
    background-color:#FCFCFC;
    background-image: url('https://by.135editor.com/img/icons/mpvoice.png');
    background-size: auto;
    background-position: left center;
    background-repeat: no-repeat;
}
覆盖themes的images目录下的所有图片

百度云链接:https://pan.baidu.com/s/1rriaUhgCeNhlgwfmzTTOJA
提取码:5j19

重写ueditor.config.js文件
/**
 * ueditor完整配置项
 * 可以在这里配置整个编辑器的特性
 */
/**************************提示********************************
 * 所有被注释的配置项均为UEditor默认值。
 * 修改默认配置请首先确保已经完全明确该参数的真实用途。
 * 主要有两种修改方案,一种是取消此处注释,然后修改成对应参数;另一种是在实例化编辑器时传入对应参数。
 * 当升级编辑器时,可直接使用旧版配置文件替换新版配置文件,不用担心旧版配置文件中因缺少新功能所需的参数而导致脚本报错。
 **************************提示********************************/

(function () {

    /**
     * 编辑器资源文件根路径。它所表示的含义是:以编辑器实例化页面为当前路径,指向编辑器资源文件(即dialog等文件夹)的路径。
     * 鉴于很多同学在使用编辑器的时候出现的种种路径问题,此处强烈建议大家使用"相对于网站根目录的相对路径"进行配置。
     * "相对于网站根目录的相对路径"也就是以斜杠开头的形如"/myProject/ueditor/"这样的路径。
     * 如果站点中有多个不在同一层级的页面需要实例化编辑器,且引用了同一UEditor的时候,此处的URL可能不适用于每个页面的编辑器。
     * 因此,UEditor提供了针对不同页面的编辑器可单独配置的根路径,具体来说,在需要实例化编辑器的页面最顶部写上如下代码即可。当然,需要令此处的URL等于对应的配置。
     * window.UEDITOR_HOME_URL = "/xxxx/xxxx/";
     */
    var URL = window.UEDITOR_HOME_URL || getUEBasePath();

    /**
     * 配置项主体。注意,此处所有涉及到路径的配置别遗漏URL变量。
     */
    window.UEDITOR_CONFIG = {

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

        // 服务器统一请求接口路径
        , serverUrl: URL + "/upload/"

        //工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义
        , toolbars: [[
            'fullscreen', 'source', '|', 'undo', 'redo', '|',
            'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
            'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
            'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
            'directionalityltr', 'directionalityrtl', 'indent', '|',
            'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',
            'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
            'simpleupload', 'insertimage', 'emotion', 'scrawl', 'insertvideo', 'music', 'attachment', 'map', 'gmap', 'insertframe', 'insertcode', 'webapp', 'pagebreak', 'template', 'background', '|',
            'horizontal', 'date', 'time', 'spechars', 'snapscreen', 'wordimage', '|',
            'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|',
            'print', 'preview', 'searchreplace', 'drafts', 'help'
        ]]
        //当鼠标放在工具栏上时显示的tooltip提示,留空支持自动多语言配置,否则以配置值为准
        //,labelMap:{
        //    'anchor':'', 'undo':''
        //}

        //语言配置项,默认是zh-cn。有需要的话也可以使用如下这样的方式来自动多语言切换,当然,前提条件是lang文件夹下存在对应的语言文件:
        //lang值也可以通过自动获取 (navigator.language||navigator.browserLanguage ||navigator.userLanguage).toLowerCase()
        //,lang:"zh-cn"
        //,langPath:URL +"lang/"

        //主题配置项,默认是default。有需要的话也可以使用如下这样的方式来自动多主题切换,当然,前提条件是themes文件夹下存在对应的主题文件:
        //现有如下皮肤:default
        //,theme:'default'
        //,themePath:URL +"themes/"

        ,zIndex : 1     //编辑器层级的基数,默认是900

        // 针对getAllHtml方法,会在对应的head标签中增加该编码设置。
        ,charset:"utf-8"

        //若实例化编辑器的页面手动修改的domain,此处需要设置为true
        //,customDomain:false

        //常用配置项目
        //,isShow : true    //默认显示编辑器

        ,textarea:'content' // 提交表单时,服务器获取编辑器提交内容的所用的参数,多实例时可以给容器name属性,会将name给定的值最为每个实例的键值,不用每次实例化的时候都设置这个值

        //,initialContent:'欢迎使用ueditor!'    //初始化编辑器的内容,也可以通过textarea/script给值,看官网例子

        //,autoClearinitialContent:true //是否自动清除编辑器初始内容,注意:如果focus属性设置为true,这个也为真,那么编辑器一上来就会触发导致初始化的内容看不到了

        //,focus:false //初始化时,是否让编辑器获得焦点true或false

        //如果自定义,最好给p标签如下的行高,要不输入中文时,会有跳动感
        //,initialStyle:'p{line-height:1em}'//编辑器层级的基数,可以用来改变字体等

        ,iframeCssUrl: URL + '/themes/iframe.css' //给编辑区域的iframe引入一个css文件

        //indentValue
        //首行缩进距离,默认是2em
        //,indentValue:'2em'

        // ,initialFrameWidth:1000  //初始化编辑器宽度,默认1000
        // ,initialFrameHeight:800  //初始化编辑器高度,默认320

        ,readonly : false //编辑器初始化结束后,编辑区域是否是只读的,默认是false

        //,autoClearEmptyNode : true //getContent时,是否删除空的inlineElement节点(包括嵌套的情况)

        //启用自动保存
        //,enableAutoSave: true
        //自动保存间隔时间, 单位ms
        ,saveInterval: 60000

        //,fullscreen : false //是否开启初始化时即全屏,默认关闭

        ,imagePopup:true      //图片操作的浮层开关,默认打开

        ,autoSyncData:true //自动同步编辑器要提交的数据
        //,emotionLocalization:false //是否开启表情本地化,默认关闭。若要开启请确保emotion文件夹下包含官网提供的images表情文件夹

        //粘贴只保留标签,去除标签所有属性
        //,retainOnlyLabelPasted: false

        //,pasteplain:false  //是否默认为纯文本粘贴。false为不使用纯文本粘贴,true为使用纯文本粘贴
        //纯文本粘贴模式下的过滤规则
        //'filterTxtRules' : function(){
        //    function transP(node){
        //        node.tagName = 'p';
        //        node.setStyle();
        //    }
        //    return {
        //        //直接删除及其字节点内容
        //        '-' : 'script style object iframe embed input select',
        //        'p': {$:{}},
        //        'br':{$:{}},
        //        'div':{'$':{}},
        //        'li':{'$':{}},
        //        'caption':transP,
        //        'th':transP,
        //        'tr':transP,
        //        'h1':transP,'h2':transP,'h3':transP,'h4':transP,'h5':transP,'h6':transP,
        //        'td':function(node){
        //            //没有内容的td直接删掉
        //            var txt = !!node.innerText();
        //            if(txt){
        //                node.parentNode.insertAfter(UE.uNode.createText(' &nbsp; &nbsp;'),node);
        //            }
        //            node.parentNode.removeChild(node,node.innerText())
        //        }
        //    }
        //}()

        //,allHtmlEnabled:false //提交到后台的数据是否包含整个html字符串

        //insertorderedlist
        //有序列表的下拉配置,值留空时支持多语言自动识别,若配置值,则以此值为准
        ,'insertorderedlist':{
             //自定的样式
             //   'num':'1,2,3...',
             //   'num1':'1),2),3)...',
             //   'num2':'(1),(2),(3)...',
             //   'cn':'一,二,三....',
             //   'cn1':'一),二),三)....',
             //   'cn2':'(一),(二),(三)....',
            //系统自带
            'decimal' : '' ,         //'1,2,3...'
             'lower-alpha' : '' ,    // 'a,b,c...'
             'lower-roman' : '' ,    //'i,ii,iii...'
             'upper-alpha' : '' , //lang   //'A,B,C'
             'upper-roman' : '' ,     //'I,II,III...'
             'cjk-ideographic' : '一、二、三、',
             'lower-greek':'α,β,γ,δ'
        }

        //insertunorderedlist
        //无序列表的下拉配置,值留空时支持多语言自动识别,若配置值,则以此值为准
        ,insertunorderedlist : {
        	//自定的样式
            //'dash' :'— 破折号', //-破折号
            //'dot':' 。 小圆圈',
        	//系统自带
            'circle' : '',  // '○ 小圆圈'
            'disc' : '',    // '● 小圆点'
            'square' : ''   //'■ 小方块'
        }
        ,listDefaultPaddingLeft : '30'//默认的左边缩进的基数倍
        //,listiconpath : 'http://bs.baidu.com/listicon/'//自定义标号的路径
        ,maxListLevel : -1 //限制可以tab的级数, 设置-1为不限制

        ,autoTransWordToList:true  //禁止word中粘贴进来的列表自动变成列表标签

        //fontfamily
        //字体设置 label留空支持多语言自动切换,若配置,则以配置值为准
        ,'fontfamily':[
            { label:'',name:'yahei',val:'微软雅黑'}, // 微软雅黑,Microsoft YaHei
            { label:'',name:'songti',val:'宋体,SimSun'},
            { label:'',name:'kaiti',val:'楷体,楷体_GB2312,SimKai'},
            { label:'',name:'heiti',val:'黑体,SimHei'},
            { label:'',name:'lishu',val:'隶书,SimLi'},
          //{ label:'文泉驿等宽正黑',name:'',val:'文泉驿等宽正黑'},
            //{ label:'文泉驿等宽微米黑',name:'',val:'文泉驿等宽微米黑'},
            { label:'站酷高端黑',name:'',val:'站酷高端黑'},
            { label:'站酷快乐体',name:'', val:'HappyZcool'},
            { label:'仿宋',name:'',val:'仿宋'},
            //{ label:'思源粗体',name:'',val:'Source Han Sans K Heavy'},
            //{ label:'思源极细',name:'',val:'Source Han Sans K ExtraLight'},
            { label:'',name:'arial',val:'arial,helvetica,sans-serif'}
        ]
        //fontsize
        //字号
		,'fontsize':[10,11,12,13,14,15,16,17,18,19,20,24,28,32,36]
        ,'letterspacing':[0,0.25,0.5,1,1.5,2,2.5,3,4,5]
		//lineheight
        //行内间距 值和显示的名字相同
        ,'lineheight':['1', '1.5','1.75','2','2.5', '3', '4', '5']

        //paragraph
        //段落格式 值留空时支持多语言自动识别,若配置,则以配置值为准
        //,'paragraph':{'p':'', 'h1':'', 'h2':'', 'h3':'', 'h4':'', 'h5':'', 'h6':''}

        //rowspacingtop
        //段间距 值和显示的名字相同
        //,'rowspacingtop':['5', '10', '15', '20', '25']

        //rowspacingBottom
        //段间距 值和显示的名字相同
        //,'rowspacingbottom':['5', '10', '15', '20', '25']

        //customstyle
        //自定义样式,不支持国际化,此处配置值即可最后显示值
        //block的元素是依据设置段落的逻辑设置的,inline的元素依据BIU的逻辑设置
        //尽量使用一些常用的标签
        //参数说明
        //tag 使用的标签名字
        //label 显示的名字也是用来标识不同类型的标识符,注意这个值每个要不同,
        //style 添加的样式
        //每一个对象就是一个自定义的样式
        //,'customstyle':[
        //    {tag:'h1', name:'tc', label:'', style:'border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;'},
        //    {tag:'h1', name:'tl',label:'', style:'border-bottom:#ccc 2px solid;padding:0 4px 0 0;margin:0 0 10px 0;'},
        //    {tag:'span',name:'im', label:'', style:'font-style:italic;font-weight:bold'},
        //    {tag:'span',name:'hi', label:'', style:'font-style:italic;font-weight:bold;color:rgb(51, 153, 204)'}
        //]

        //打开右键菜单功能
        ,enableContextMenu: true
        //右键菜单的内容,可以参考plugins/contextmenu.js里边的默认菜单的例子,label留空支持国际化,否则以此配置为准
        //,contextMenu:[
        //    {
        //        label:'',       //显示的名称
        //        cmdName:'selectall',//执行的command命令,当点击这个右键菜单时
        //        //exec可选,有了exec就会在点击时执行这个function,优先级高于cmdName
        //        exec:function () {
        //            //this是当前编辑器的实例
        //            //this.ui._dialogs['inserttableDialog'].open();
        //        }
        //    }
        //]

        //快捷菜单
		,shortcutMenu:["fontfamily","fontsize","|",
        "bold","italic","underline",'fontborder','strikethrough',"forecolor","shadowcolor","insertorderedlist","insertunorderedlist","superscript", "subscript",
        "|","justifyleft","justifycenter","justifyright",'justifyjustify',"indent","rowspacingtop",'rowspacingbottom',"lineheight",'letterspacing']

        ,newShortcutMenu:["fontfamily","fontsize","justifyleft","justifycenter","justifyright",'justifyjustify',"indent","outpadding",'letterspacing','<br>', "rowspacingtop",'rowspacingbottom',"lineheight",
        "insertorderedlist","insertunorderedlist","bold","italic","underline",'fontborder','strikethrough','<br>',"forecolor","shadowcolor","backcolor","superscript", "subscript",'link','unlink']
        //elementPathEnabled
        //是否启用元素路径,默认是显示
        ,elementPathEnabled : false

        //wordCount
        ,wordCount:true          //是否开启字数统计
        //,maximumWords:10000       //允许的最大字符数
        //字数统计提示,{#count}代表当前字数,{#leave}代表还可以输入多少字符数,留空支持多语言自动切换,否则按此配置显示
        ,wordCountMsg:'当前已输入 {#count} 个字符,您还可以输入{#leave} 个字符'   //当前已输入 {#count} 个字符,您还可以输入{#leave} 个字符
        //超出字数限制提示  留空支持多语言自动切换,否则按此配置显示
        //,wordOverFlowMsg:''    //<span style="color:red;">你输入的字符个数已经超出最大允许值,服务器可能会拒绝保存!</span>

        //tab
        //点击tab键时移动的距离,tabSize倍数,tabNode什么字符做为单位
        //,tabSize:4
        //,tabNode:'&nbsp;'

        //removeFormat
        //清除格式时可以删除的标签和属性
        //removeForamtTags标签
        ,removeFormatTags:'a,b,big,code,del,dfn,em,font,i,section,blockquote,pre,fieldset,ins,kbd,q,samp,small,span,label,strike,strong,sub,sup,tt,u,var'
        //removeFormatAttributes属性
        ,removeFormatAttributes:'class,style,lang,width,accuse,height,align,hspace,valign,data-width,data-brushtype,opacity,border,title,placeholder'

        //undo
        //可以最多回退的次数,默认20
        ,maxUndoCount:20
        //当输入的字符数超过该值时,保存一次现场
        //,maxInputCount:1

        //autoHeightEnabled
        // 是否自动长高,默认true
        ,autoHeightEnabled:false

        //scaleEnabled
        //是否可以拉伸长高,默认true(当开启时,自动长高失效)
        ,scaleEnabled:false
		,imageScaleEnabled:true
        //,minFrameWidth:800    //编辑器拖动时最小宽度,默认800
        //,minFrameHeight:220  //编辑器拖动时最小高度,默认220

        //autoFloatEnabled
        //是否保持toolbar的位置不动,默认true
        ,autoFloatEnabled:false
        //浮动时工具栏距离浏览器顶部的高度,用于某些具有固定头部的页面
        //,topOffset:30
        //编辑器底部距离工具栏高度(如果参数大于等于编辑器高度,则设置无效)
        //,toolbarTopOffset:400
		,'remoteName':'#remoteName','remoteSummary':'#remoteSummary','remoteCoverimg':'#remoteCoverimg'
        //设置远程图片是否抓取到本地保存
        ,catchRemoteImageEnable: true //设置是否抓取远程图片

        //pageBreakTag
        //分页标识符,默认是_ueditor_page_break_tag_
        //,pageBreakTag:'_ueditor_page_break_tag_'

        // autotypeset
        // 自动排版参数
        ,autotypeset: {
            mergeEmptyline: true,           //合并空行
            removeClass: false,              //去掉冗余的class
            removeEmptyline: false,         //去掉空行
            textAlign:false,
            //textAlign:"left",               //段落的排版方式,可以是 left,right,center,justify 去掉这个属性表示不执行排版
            imageBlockLine: false,       //图片的浮动方式,独占一行剧中,左右浮动,默认: center,left,right,none 去掉这个属性表示不执行排版
            pasteFilter: false,             //根据规则过滤没事粘贴进来的内容
            clearFontSize: false,           //去掉所有的内嵌字号,使用编辑器默认的字号
            clearFontFamily: false,         //去掉所有的内嵌字体,使用编辑器默认的字体
            removeEmptyNode: false,         // 去掉空节点
            //可以去掉的标签
            //removeTagNames: {标签名字:1},
            indent: false,                  // 行首缩进
            indentValue : '2em',            //行首缩进的大小
            bdc2sb: false,
            tobdc: false
        }

        //tableDragable
        //表格是否可以拖拽
        //,tableDragable: true



        //sourceEditor
        //源码的查看方式,codemirror 是代码高亮,textarea是文本框,默认是codemirror
        //注意默认codemirror只能在ie8+和非ie中使用
        ,sourceEditor:"codemirror"
        //如果sourceEditor是codemirror,还用配置一下两个参数
        //codeMirrorJsUrl js加载的路径,默认是 URL + "third-party/codemirror/codemirror.js"
        //,codeMirrorJsUrl:URL + "third-party/codemirror/codemirror.js"
        //codeMirrorCssUrl css加载的路径,默认是 URL + "third-party/codemirror/codemirror.css"
        //,codeMirrorCssUrl:URL + "third-party/codemirror/codemirror.css"
        //编辑器初始化完成后是否进入源码模式,默认为否。
        //,sourceEditorFirst:false

        //iframeUrlMap
        //dialog内容的路径 ~会被替换成URL,垓属性一旦打开,将覆盖所有的dialog的默认路径
        //,iframeUrlMap:{
        //    'anchor':'~/dialogs/anchor/anchor.html',
        //}

        //allowLinkProtocol 允许的链接地址,有这些前缀的链接地址不会自动添加http
        //, allowLinkProtocols: ['http:', 'https:', '#', '/', 'ftp:', 'mailto:', 'tel:', 'git:', 'svn:']

        //webAppKey 百度应用的APIkey,每个站长必须首先去百度官网注册一个key后方能正常使用app功能,注册介绍,http://app.baidu.com/static/cms/getapikey.html
        //, webAppKey: ""

        //默认过滤规则相关配置项目
        ,disabledTableInTable:false  //禁止表格嵌套
        //,allowDivTransToP:true      //允许进入编辑器的div标签自动变成p标签
        ,rgb2Hex:true               //默认产出的数据中的color自动从rgb格式变成16进制格式

		// xss 过滤是否开启,inserthtml等操作
		,xssFilterRules: true
		//input xss过滤
		,inputXssFilter: true
		//output xss过滤
		,outputXssFilter: true
		// xss过滤白名单 名单来源: https://raw.githubusercontent.com/leizongmin/js-xss/master/lib/default.js
		// ,whitList: {
		// 	a:      ['target', 'href', 'title', 'class', 'style'],
		// 	abbr:   ['title', 'class', 'style'],
		// 	address: ['class', 'style'],
		// 	area:   ['shape', 'coords', 'href', 'alt'],
		// 	article: [],
		// 	aside:  [],
		// 	audio:  ['autoplay', 'controls', 'loop', 'preload', 'src', 'class', 'style'],
		// 	b:      ['class', 'style'],
		// 	bdi:    ['dir'],
		// 	bdo:    ['dir'],
		// 	big:    [],
		// 	blockquote: ['cite', 'class', 'style'],
		// 	br:     [],
		// 	caption: ['class', 'style'],
		// 	center: [],
		// 	cite:   [],
		// 	code:   ['class', 'style'],
		// 	col:    ['align', 'valign', 'span', 'width', 'class', 'style'],
		// 	colgroup: ['align', 'valign', 'span', 'width', 'class', 'style'],
		// 	dd:     ['class', 'style'],
		// 	del:    ['datetime'],
		// 	details: ['open'],
		// 	div:    ['class', 'style'],
		// 	dl:     ['class', 'style'],
		// 	dt:     ['class', 'style'],
		// 	em:     ['class', 'style'],
		// 	font:   ['color', 'size', 'face'],
		// 	footer: [],
		// 	h1:     ['class', 'style'],
		// 	h2:     ['class', 'style'],
		// 	h3:     ['class', 'style'],
		// 	h4:     ['class', 'style'],
		// 	h5:     ['class', 'style'],
		// 	h6:     ['class', 'style'],
		// 	header: [],
		// 	hr:     [],
		// 	i:      ['class', 'style'],
		// 	img:    ['src', 'alt', 'title', 'width', 'height', 'id', '_src', 'loadingclass', 'class', 'data-latex'],
		// 	ins:    ['datetime'],
		// 	li:     ['class', 'style'],
		// 	mark:   [],
		// 	nav:    [],
		// 	ol:     ['class', 'style'],
		// 	p:      ['class', 'style'],
		// 	pre:    ['class', 'style'],
		// 	s:      [],
		// 	section:[],
		// 	small:  [],
		// 	span:   ['class', 'style'],
		// 	sub:    ['class', 'style'],
		// 	sup:    ['class', 'style'],
		// 	strong: ['class', 'style'],
		// 	table:  ['width', 'border', 'align', 'valign', 'class', 'style'],
		// 	tbody:  ['align', 'valign', 'class', 'style'],
		// 	td:     ['width', 'rowspan', 'colspan', 'align', 'valign', 'class', 'style'],
		// 	tfoot:  ['align', 'valign', 'class', 'style'],
		// 	th:     ['width', 'rowspan', 'colspan', 'align', 'valign', 'class', 'style'],
		// 	thead:  ['align', 'valign', 'class', 'style'],
		// 	tr:     ['rowspan', 'align', 'valign', 'class', 'style'],
		// 	tt:     [],
		// 	u:      [],
		// 	ul:     ['class', 'style'],
		// 	video:  ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width', 'class', 'style']
		// }
    };

    function getUEBasePath(docUrl, confUrl) {
        return getBasePath(docUrl || self.document.URL || self.location.href, confUrl || getConfigFilePath());

    }

    function getConfigFilePath() {

        var configPath = document.getElementsByTagName('script');

        return configPath[ configPath.length - 1 ].src;

    }

    function getBasePath(docUrl, confUrl) {

        var basePath = confUrl;


        if (/^(\/|\\\\)/.test(confUrl)) {

            basePath = /^.+?\w(\/|\\\\)/.exec(docUrl)[0] + confUrl.replace(/^(\/|\\\\)/, '');

        } else if (!/^[a-z]+:/i.test(confUrl)) {

            docUrl = docUrl.split("#")[0].split("?")[0].replace(/[^\\\/]+$/, '');

            basePath = docUrl + "" + confUrl;

        }

        return optimizationPath(basePath);

    }

    function optimizationPath(path) {

        var protocol = /^[a-z]+:\/\//.exec(path)[ 0 ],
            tmp = null,
            res = [];

        path = path.replace(protocol, "").split("?")[0].split("#")[0];

        path = path.replace(/\\/g, '/').split(/\//);

        path[ path.length - 1 ] = "";

        while (path.length) {

            if (( tmp = path.shift() ) === "..") {
                res.pop();
            } else if (tmp !== ".") {
                res.push(tmp);
            }

        }

        return protocol + res.join("/");

    }

    window.UE = {
        getUEBasePath: getUEBasePath
    };

})();

修改index.html文件

修改index.html文件body标签中的内容即可

<script id="editor" type="text/plain"></script>
<script type="text/javascript" src="{{ url_for('static',filename='ueditor/plugins/135editor.js') }}"></script>
<script type="text/javascript">
            //实例化编辑器
            //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例
            current_editor = UE.getEditor('editor',{
                serverUrl:'/upload/',
                initialFrameHeight:400,
                focus:true,
                toolbars:[
                ['bold','italic', 'underline', 'fontborder', 'strikethrough',  '135editor','rowspacingtop', 'rowspacingbottom', 'lineheight','removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|','superscript', 'subscript' ]],
                focusInEnd:true
            });
查看效果

最后就是检验效果的时候到了,先看看135编辑器给的demo案例中的编辑器吧

135编辑器demo
135编辑器demo笔者完成的demo:
笔者完成的demo不仅仅是表面一样,连内容也是一样,给你们看看135编辑器的内容效果。

内容效果:
内容效果
如果在实现135编辑器的时候出现任何情况都可以联系笔者,笔者尽可能为大家解决烦恼,以上内容部分是参照http://flask123.sinaapp.com/article/47/文章所写。

QQ联系方式:1670044143

猜你喜欢

转载自blog.csdn.net/qq_42279077/article/details/91344527