精华内容
下载资源
问答
  • 2018-12-09 19:31:56

    首先我们来看一下微信官方关于图文消息发送给出的文档说明

    小程序卡片跳转小程序,代码示例:

    <mp-miniprogram data-miniprogram-appid="wx123123123" data-miniprogram-path="pages/index/index" data-miniprogram-title="小程序示例" data-progarm-imageurl="http://mmbizqbic.cn/demo.jpg"></mp-miniprogram>

    如上图所示,若要向微信同步图文消息发送小程序卡片,上面几个参数必须要按照固定的条件来获取到。

    下面我来看下具体代码实现

    // 获取到的小程序对象
        var smallCodeObj = linkTools.deepCopy(this.rotinueObj.selectedRotinueObj);
        var p = '';
        var appid = smallCodeObj.appId; // 小程序appid
        var nickName = smallCodeObj.mpName; // 小程序名字
        var path = 'pages/tabs/tabs'; // 待定 小程序的url
        var title= this.rotinueObj.innerFormData.title; // 卡片标题
        var imgUrl = this.rotinueObj.selectedImg.url; // 卡片的url
        var cdnpath = appCtx.cdnPath;
    
        p = `<iframe class=\"res_iframe weapp_app_iframe js_editor_weapp wxCard\" src=\"${cdnpath}/linkcrm/marketing/wx_small_code.html?appid=${appid}&&nickName=${nickName}&&path=${path}&&title=${title}&&imgUrl=${imgUrl}\" frameborder=\"0\" data-miniprogram-appid=\"${appid}\" data-miniprogram-nickname=\"${nickName}\" data-miniprogram-title=\"${title}\" data-miniprogram-imageUrl=\"${imgUrl}\" data-miniprogram-path=\"${path}\">
                     </iframe><p><mp-miniprogram data-miniprogram-appid=\"${appid}\" data-miniprogram-path=\"${path}\" data-miniprogram-title=\"${title}\" data-miniprogram-imageurl=\"${imgUrl}\"></mp-miniprogram></p >`;

    然后就是请求后台的接口,将对应的内容给传递给后台在请求微信服务器把数据同步过去。具体请求后台方法就不贴代码了,之前在这个地方遇到一个坑,就是微信服务器那边接收我的文本编辑器里面的内容,可以是html,但我把对应的html片段传过去之后,会很诡异的报错45166;然后查询了一些资料,发现我的content里面的html代码格式有问题,错误的代码我就不展示了,我把没问题的代码格式与大家共勉。

    {
    	"articles": [{
    		"thumb_media_id": "nLSuWIlNwk1BMQ6miOpRVyvYGsiXq7tKuorzOM2_gmk",
    		"author": "123123",
    		"digest": "啦啦啦啦",
    		"show_cover_pic": "1",
    		"title": "九福数据测试",
    		"content": "<iframe class=\"res_iframe weapp_app_iframe js_editor_weapp wxCard\" src=\"${cdnpath}/linkcrm/marketing/wx_small_code.html?appid=${appid}&&nickName=${nickName}&&path=${path}&&title=${title}&&imgUrl=${imgUrl}\" frameborder=\"0\" data-miniprogram-appid=\"${appid}\" data-miniprogram-nickname=\"${nickName}\" data-miniprogram-title=\"${title}\" data-miniprogram-imageUrl=\"${imgUrl}\" data-miniprogram-path=\"${path}\">
                     </iframe><p><mp-miniprogram data-miniprogram-appid=\"wx31ccc23d0caff0bf\" data-miniprogram-path=\"pages/tabs/tabs\" data-miniprogram-title=\"小程序示例\" data-miniprogram-imageurl=\"https://mmbiz.qpic.cn/mmbiz_png/6bZBMcricibHHeSekWELdvz3CFSWtRzgLp3v5L1WDhUTxdzPicKrFr1BYhVeUcYMRh3Is7R7Cn8GpVdrHaWWsdibhA/0?wx_fmt=png\"></mp-miniprogram><p>222222</p ></p >"
    	}]
    }

    主要看content里面的代码,传给微信时双引号必须为 \"  ;然后这样基本就完了,大家赶快去试试吧!下面贴上效果图:

     

    这里我们就可以在微信公众号给客户发送消息,客户就可以通过点击小卡片直接跳转至对应的小程序。

    以下是我做这个功能的一些心得。与大家共勉

    1、你要发送的小程序必须和你发送消息的公众号关联在一起,具体怎么关联可自行百度;

    2、发送小程序卡片的封面图片必须是已经上传至微信服务器的且必须是1080*864像素的

    3、就是发送显示同步至微信富文本编辑器的html代码必须按照以上代码验样例一样的格式

    更多相关内容
  • UEditor是由百度「FEX前端研发团队」开发的所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码。 本文以最新版本的1.4.3.3版本为教程来讲述 具体文档...

    UEditor简介

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

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

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

    135编辑器简介

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

    免费版:

    免费版

    收费版:

    收费版

    使用优势

    功能UEditor135编辑器
    上传图片需配置上传图片的选项无需配置(上传的图片由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

    展开全文
  • 微信公众号的人群里面,不乏十分勤奋者。看看他们使用的排版工具,便知道为了排版一篇文章,他们要耗费多少辛劳了。 请注意,他们是一个标题、一个段落、一个引言这样的用样式模板插入内容。这样排版的结果...

    懒人的烦恼

    写微信公众号的人群里面,不乏十分勤奋者。看看他们使用的排版工具,便知道为了排版一篇文章,他们要耗费多少辛劳了。

    img_f0705e240827d1cdd1fe1273a01e4310.jpe

    请注意,他们是一个标题、一个段落、一个引言这样的用样式模板插入内容。这样排版的结果确实会符合作者的要求。但是这么排版我真的做不来。

    我连做博士毕业论文都不用Word啊!

    我用的是LaTeX。

    为什么这么标新立异?并非有意为之,而是用LaTeX的话只需要码字儿就可以了。样式的事儿,都交给程序去操心岂不更好?

    这几年,Markdown开始兴起,我现在除了数学公式,连LaTeX都懒得用了。

    你不难看出我的哲学——没错,怎么省事儿怎么来。

    但省事儿的同时,还需要满足需求。

    微信公众号文章不是学术论文,公式和参考文献都很少见。里面最常见的样式无非是标题、正文、引用和图片等。这些东西Markdown处理起来得心应手。

    曾经有一段我用hexo写博客,就是这么做的,采用Markdown排版效果一直挺好。

    但是,在微信公众号排版上我遇到了挫折。因为微信公众号不支持 Markdown 直接排版。到我写作这篇文章的时候,还只支持富文本格式。

    img_d46674a3710fcd735a01e3b93a98b1d1.jpe

    这就意味着我每次用Markdown写好文章,预览没有问题之后,还需要找个地方把Markdown转换为富文本。

    一开始,我偷懒,在微信公众平台编辑器里用Markdown Here直接做这个转换。结果预览的时候没问题,群发之后文内图片全都消失了。微信公众号一旦群发消息就无法修改,而且我的个人公众号每天只能发送一条消息。搞得我郁闷了好几个小时。

    后来我陆续尝试了几个微信公众号第三方编辑工具。发现其中135编辑器还算是差强人意。

    在这个编辑器里面用Markdown Here生成HTML,拷贝出来的时候就直接被转换成为了富文本,贴到微信公众平台编辑器里标题加黑字号与图片显示一切正常,发布之后验证图片也能正常显示。

    于是我就认为自己已经找到了终南捷径。

    可是,时间长了,我就发现了问题——虽然排版出来图片是正常的,可是其他样式全都乱套了。标题前后间距彻底消失,而且正文文字的行距很小,全都堆在了一起,非常影响阅读体验。

    img_28fff4cf5b4b4c33b7844242b1e3d23f.png

    昨天早上,我6点多爬起来,把一篇文章修订之后,就打算在微信公众号发出去。

    按照老样子粘贴过去富文本,怎么看怎么别扭。

    于是尝试了若干种不同的第三方编辑器,发现都不理想,有些干脆就无法保留任何样式。

    突然发现了135编辑器弹窗里面推广VIP功能。

    img_8c40c6a224d5ec3fc7ae2cba6f1c6798.jpe

    之前一直把这个编辑器当成中转站,我从来就没有关注过其中的“高级”功能。这次看了一眼,发现了“一键排版”。而且,其中但凡是看得过去的主题,全都得VIP才能用。对一个懒人来说,这种关键词的诱惑哪里受得了?立即就下单买了一个月的。

    您还真别说,一键排版之后,立刻行间距和标题格式都好看了。我使用了“简约”模板,看着觉得赏心悦目。

    嗯,这样好!

    ……

    咦,不对啊!

    怎么标题变出来这么多?!

    img_a96cd0721694f0a47e32c4c90ce2c60b.jpe

    定睛一看,原来这个一键排版不够智能,居然分辨不出来Markdown Here转换之后的文本里面哪一行是标题!作为补偿,它会让使用者设置一个字数阈值(默认20个字),低于这个字数阈值,就被认为是标题。

    img_5b9d5ee01ccf8718457c7b15536261e4.jpe

    这不是搞笑吗?!

    我喜欢用短句啊!

    更糟糕的是,排版之后,还无法方便地手动对标题识别结果进行调整。我为了迁就它,只好把阈值降低字数,然后往文字后面加入标点符号,或者把行合并。怎么看怎么觉得别扭。

    7点半,终于弄得差不多了。我把排版结果拷贝到微信公众平台编辑器里面。预览一下,觉得可以,就发出去了。

    发出去之后,吓了一大跳——文中所有的字体加粗全部被取消了。

    这就叫“一键排版”?

    得,认了,幸好我只买了一个月的VIP。

    醍醐灌顶

    今天,从茫茫文海里面一眼看到了Jason Ng的文章《可能吧公众号的文章是如何排版的?》。

    Jason是我非常钦佩的作者,他的公众号排版精良,我很羡慕。开始以为他要讲自己是如何用第三方编辑器一个段落一个段落手动调样式呢,我打算接受一下吃苦耐劳的教育,好好对照反省自己的懒惰。可是越读下去我越开心——他跟我一样用Markdown啊!

    但是不同的是,高手的概念比我清晰许多。

    既然Markdown生成的是HTML,那调CSS不就好了吗?

    对啊!

    为什么要让Markdown Here这么一个组件来决定我的文章排版样式风格呢?把Markdown转换为HTML,然后用富文本方式拷贝到微信公众平台编辑器里面,不就完事大吉了嘛。

    我立即尝试,效果非常好。但是却立即发现了问题。这个问题在于Jason对读者的预期。

    对于“一点都不懂 HTML 和 CSS”的读者,Jason给出了两种解决办法。

    方法一是你需要认识一个设计师和一个前端工程师,这个要求稍微有些高,这里咱们先不讨论了。

    方法二是自己动手学习,看到这里估计许多人都跃跃欲试。

    可能吧的读者中,假设有10个人对微信公众号Markdown排版感兴趣,能有5个照着方法二完成吗?我不那么有信心。

    为什么?

    因为Jason的操作指南里面,有这样一句:

    花 1 天时间,学会如何写一个简单包含 replacements 函数的 Python 脚本。

    实话实说,没有接触过编程的人,打算用这速度学Python,还能坚持下来,我觉得可能性很小。

    Jason这样想完全可以理解,因为人以群分,可以想象他认识的人中,许多虽然没有技术基础,但是愿意保持开放的心态来学习新东西。然而公众号的对象并不只是他的朋友们。许多没有技术基础的人,在读到这一条的时候,会立即退缩不前。这不是我的臆断,你去普通高校的文科专业教几年技术类课程,恐怕你的想法跟我相去无几。

    这就好像一个NBA教练让球员好好练练反手扣篮一样——他的球员都是2米左右的巨人啊,稍加努力就可以完成了。然而同样是这个NBA教练,就算他把反手扣篮的诀窍写下来白送给我,我也不会去尝试的。

    好消息是,经过我的摸索,发现了一个事实——你不用学会Python脚本,也能以懒人的办法用Markdown排版微信公众号文章。

    流程介绍

    工欲善其事,必先利其器。

    Jason在文章里面推荐了Ulysses,确实是写作利器,我深表赞同。

    这里我推荐一个配套的软件,叫做Marked2。

    img_99599bdf828c55413f29e307c2a713d3.png

    Ulysses中的文章可以轻松导出到Marked2里面预览,然后可以带样式导出为HTML。

    你不需要用一个脚本去替换段落和标题标签了,你只需要修改Marked2里面的用户定制CSS就行。

    img_525537c4098e1ad6fe1c847a1e580dbc.jpe

    我这里根据Jason文中提到的样式信息,修改了其中正文段落样式部分:

    p,h5 {
        /*font-size: 1.1429em;*/
        /*line-height: 1.3125em;*/
        margin: 1.3125em 0;
        font-size: 15px;
        letter-spacing: 1px;
        line-height: 28px;
    }
    

    在浏览器里面预览导出的HTML文件,效果是这样的:

    img_461a5563c11a7488abe26c4758062afd.jpe

    Jason推荐在CKEditor在线编辑器里面把HTML转换为富文本,然后拷贝到微信公众平台编辑器。

    我尝试了一下,发觉这个编辑器确实强大,完全版里面选项很丰富。但对于初学者而言,使用方法并不直观。打开网站主页,你甚至都找不到HTML源码应该贴在哪儿。

    img_64235d6458ee819272b63a5ebc0c111b.jpe

    不过干嘛非要执着于某个在线编辑器呢?找一个打开后立即能用的不好吗?

    我找到了wangEditor编辑器,开源免费。

    img_624641cd8a5879776af424611287e756.jpe

    插入HTML源码后,预览一下,效果是一致的。

    贴到微信公众平台编辑器里面,发现所有自定义样式全部都可以保留。

    这便是我在Jason的启发下,整理出来的懒人Markdown排版方法。困扰了我多日的微信公众号排版问题,就这样解决了。


    延伸阅读:

    展开全文
  • 富文本编辑器使用详细介绍

    千次阅读 2019-12-05 20:38:14
    目录 第一种NicEdit 官网描述: 官网地址 如何使用 第二种kindeditor ...这里介绍两种常见的富文本使用方式 第一种NicEdit 官网描述: What is NicEdit? NicEdit is a Lightweight, Cross Platform,...

    目录

     

    一、概述

    二、举例使用

    第一种NicEdit

    官网描述:

    官网地址

    如何使用

    第二种kindeditor

    官网描述

    官网地址

    第三种:Editor.md

    基本使用

    图片上传问题

    表情包

    文章展示


    一、概述

    其实这个就是富文本编辑器,市面上有许多非常成熟的富文本编辑器,比如:

    • Editor.md——功能非常丰富的编辑器,左端编辑,右端预览,非常方便,完全免费

      • 官网:https://pandao.github.io/editor.md/

    • wangEditor——基于javascript和css开发的 Web富文本编辑器, 轻量、简洁、界面美观、易用、开源免费。(个人最喜欢的一款)

      • 官网:http://www.wangeditor.com/

    • TinyMCE——TinyMCE是一个轻量级的基于浏览器的所见即所得编辑器,由JavaScript写成。它对IE6+和Firefox1.5+都有着非常良好的支持。功能齐全,界面美观,就是文档是英文的,对开发人员英文水平有一定要求。

      • 官网:https://www.tiny.cloud/docs/demo/full-featured/

      • 博客园

    • 百度ueditor——UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,功能齐全,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码,缺点是已经没有更新了

      • 官网:https://ueditor.baidu.com/website/onlinedemo.html

    • kindeditor——界面经典。

      • 官网:http://kindeditor.net/demo.php

    • Textbox——Textbox是一款极简但功能强大的在线文本编辑器,支持桌面设备和移动设备。主要功能包含内置的图像处理和存储、文件拖放、拼写检查和自动更正。此外,该工具还实现了屏幕阅读器等辅助技术,并符合WAI-ARIA可访问性标准。

      • 官网:https://textbox.io/

    • CKEditor——国外的,界面美观。

      • 官网:https://ckeditor.com/ckeditor-5/demo/

    • quill——功能强大,还可以编辑公式等

      • 官网:https://quilljs.com/

    • simditor——界面美观,功能较全。

      • 官网:https://simditor.tower.im/

    • summernote——UI好看,精美

      • 官网:https://summernote.org/

    • jodit——功能齐全

      • 官网:https://xdsoft.net/jodit/

    • froala Editor——界面非常好看,功能非常强大,非常好用(非免费)

      • 官网:https://www.froala.com/wysiwyg-editor

    总之,目前可用的富文本编辑器有很多......这只是其中的一部分

    二、举例使用

    第一种NicEdit

    官网描述:

    What is NicEdit?

    NicEdit is a Lightweight, Cross Platform, Inline Content Editor to allow easy editing of web site content on the fly in the browser.

    NicEdit Javascript integrates into any site in seconds to make any element/div editable or convert standard textareas to rich text editing

    什么是NicEdit?
    NicEdit是一个轻量级,跨平台的内联内容编辑器,可以轻松地在浏览器中即时编辑网站内容。
    NicEdit Javascript可以在几秒钟内集成到任何站点中,以使任何元素/ div可编辑或将标准文本区域转换为富文本编辑。

    官网地址

    http://www.nicedit.com/index.php

    如何使用

    只需引入官网的一个js文件和一个图片即可

    <script type="text/javascript" src="../nicEdit.js"></script>
    <script type="text/javascript">
    	bkLib.onDomLoaded(function() { nicEditors.allTextAreas() });
    </script>
    
    <h4>First Textarea</h4>
    <textarea name="area1" cols="40"></textarea>

    效果展示

    其中用到的gif图片的位置可以修改js文件配置。

    案例代码获取方式 ,关注微信公众号    java一号  回复  “富文本” 即可

    第二种kindeditor

    官网描述

    KindEditor 是什么?

    KindEditor 是一套开源的在线HTML编辑器,主要用于让用户在网站上获得所见即所得编辑效果,开发人员可以用 KindEditor 把传统的多行文本输入框(textarea)替换为可视化的富文本输入框。 KindEditor 使用 JavaScript 编写,可以无缝地与 Java、.NET、PHP、ASP 等程序集成,比较适合在 CMS、商城、论坛、博客、Wiki、电子邮件等互联网应用上使用。

    官网地址

    http://kindeditor.net/demo.php

    如何使用

    1.1.  使用方法

    第一步:在jsp中引入KindEditor的css和js代码。

    <link href="kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet">
     <script src="jquery-1.10.1.min.js"></script>
     <script type="text/javascript" charset="utf-8" src="kindeditor-4.1.10/kindeditor-all-min.js"></script>
     <script type="text/javascript" charset="utf-8" src="kindeditor-4.1.10/lang/zh_CN.js"></script>

     

    第二步:在表单中添加一个textarea控件。是一个富文本编辑器的载体。类似数据源。

    <form action="editor.html" method="post">
        <textarea style="width:800px;height:300px;visibility:hidden;" name="desc" id="editor"></textarea>
        <input type="submit"/>
     </form>

     

    第三步:初始化富文本编辑器。使用官方提供的方法初始化。

    <script type="text/javascript" >
        var kingEditorParams ={
            filePostName  : "file",//指定上传文件参数名称
            uploadJson:'upload2.html',//指定上传文件请求的url。
            dir:"image"//上传类型,分别为image、flash、media、file
        }
        var editor;
        $(function () {
            editor=KindEditor.create($("#editor"),kingEditorParams);
        })
     </script>

    js提交请求的时候,同步富文本框到textarea

    editor.sync();//同步富文本编辑器到textarea

    上传图片时controller方法:

    @ResponseBody

    String json = "{\"error\":0,\"url\":\"" + url + "\"}";

    第三种:Editor.md

    作为一个资深码农,Mardown必然是程序猿喜欢的格式,看下面,

    我们可以在官网下载它:https://pandao.github.io/editor.md/ , 得到它的压缩包!

    解压以后,在examples目录下面,可以看到他的很多案例使用!学习,其实就是看人家怎么写的,然后进行模仿就好了!

    基本使用

    我们可以将整个解压的文件倒入我们的项目,将一些无用的测试和案例删掉即可!

    1、导入 editor.md 资源 ,删除多余文件

    2、编辑文章页面 editor.html、需要引入 jQuery;

    <!DOCTYPE html>
    <html class="x-admin-sm" lang="zh" xmlns:th="http://www.thymeleaf.org">
    
    <head>
       <meta charset="UTF-8">
       <title>Blog</title>
       <meta name="renderer" content="webkit">
       <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
       <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
       <!--Editor.md-->
       <link rel="stylesheet" th:href="@{/editormd/css/editormd.css}"/>
       <link rel="shortcut icon" href="https://pandao.github.io/editor.md/favicon.ico" type="image/x-icon" />
    </head>
    
    <body>
    
    <div class="layui-fluid">
       <div class="layui-row layui-col-space15">
           <div class="layui-col-md12">
               <!--博客表单-->
               <form name="mdEditorForm">
                   <div>
                      标题:<input type="text" name="title">
                   </div>
                   <div>
                      作者:<input type="text" name="author">
                   </div>
                   <div id="article-content">
                       <textarea name="content" id="content" style="display:none;"> </textarea>
                   </div>
               </form>
    
           </div>
       </div>
    </div>
    </body>
    
    <!--editormd-->
    <script th:src="@{/editormd/lib/jquery.min.js}"></script>
    <script th:src="@{/editormd/editormd.js}"></script>
    
    <script type="text/javascript">
       var testEditor;
    
       //window.onload = function(){ }
       $(function() {
           testEditor = editormd("article-content", {
               width : "95%",
               height : 400,
               syncScrolling : "single",
               path : "../editormd/lib/",
               saveHTMLToTextarea : true,    // 保存 HTML 到 Textarea
               emoji: true,
               theme: "dark",//工具栏主题
               previewTheme: "dark",//预览主题
               editorTheme: "pastel-on-dark",//编辑主题
               tex : true,                   // 开启科学公式TeX语言支持,默认关闭
               flowChart : true,             // 开启流程图支持,默认关闭
               sequenceDiagram : true,       // 开启时序/序列图支持,默认关闭,
               //图片上传
               imageUpload : true,
               imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
               imageUploadURL : "/article/file/upload",
               onload : function() {
                   console.log('onload', this);
              },
               /*指定需要显示的功能按钮*/
               toolbarIcons : function() {
                   return ["undo","redo","|",
                       "bold","del","italic","quote","ucwords","uppercase","lowercase","|",
                       "h1","h2","h3","h4","h5","h6","|",
                       "list-ul","list-ol","hr","|",
                       "link","reference-link","image","code","preformatted-text",
                       "code-block","table","datetime","emoji","html-entities","pagebreak","|",
                       "goto-line","watch","preview","fullscreen","clear","search","|",
                       "help","info","releaseIcon", "index"]
              },
    
               /*自定义功能按钮,下面我自定义了2个,一个是发布,一个是返回首页*/
               toolbarIconTexts : {
                   releaseIcon : "<span bgcolor=\"gray\">发布</span>",
                   index : "<span bgcolor=\"red\">返回首页</span>",
              },
    
               /*给自定义按钮指定回调函数*/
               toolbarHandlers:{
                   releaseIcon : function(cm, icon, cursor, selection) {
                       //表单提交
                       mdEditorForm.method = "post";
                       mdEditorForm.action = "/article/addArticle";//提交至服务器的路径
                       mdEditorForm.submit();
                  },
                   index : function(){
                       window.location.href = '/';
                  },
              }
          });
      });
    </script>
    
    </html>
    @Controller
    @RequestMapping("/article")
    public class ArticleController {
    
       @GetMapping("/toEditor")
       public String toEditor(){
           return "editor";
      }
       
       @PostMapping("/addArticle")
       public String addArticle(Article article){
           articleMapper.addArticle(article);
           return "editor";
      }
       
    }

    图片上传问题

    1、前端js中添加配置

    //图片上传
    imageUpload : true,
    imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
    imageUploadURL : "/article/file/upload", // //这个是上传图片时的访问地址

    2、后端请求,接收保存这个图片, 需要导入 FastJson 的依赖!

    //博客图片上传问题
    @RequestMapping("/file/upload")
    @ResponseBody
    public JSONObject fileUpload(@RequestParam(value = "editormd-image-file", required = true) MultipartFile file, HttpServletRequest request) throws IOException {
        //上传路径保存设置
    
        //获得SpringBoot当前项目的路径:System.getProperty("user.dir")
        String path = System.getProperty("user.dir")+"/upload/";
    
        //按照月份进行分类:
        Calendar instance = Calendar.getInstance();
        String month = (instance.get(Calendar.MONTH) + 1)+"月";
        path = path+month;
    
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
    
        //上传文件地址
        System.out.println("上传文件保存地址:"+realPath);
    
        //解决文件名字问题:我们使用uuid;
        String filename = "ks-"+UUID.randomUUID().toString().replaceAll("-", "");
        //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
        file.transferTo(new File(realPath +"/"+ filename));
    
        //给editormd进行回调
        JSONObject res = new JSONObject();
        res.put("url","/upload/"+month+"/"+ filename);
        res.put("success", 1);
        res.put("message", "upload success!");
    
        return res;
    }

    3、解决文件回显显示的问题,设置虚拟目录映射!在我们自己拓展的MvcConfig中进行配置即可!

    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer {
    
        // 文件保存在真实目录/upload/下,
        // 访问的时候使用虚路径/upload,比如文件名为1.png,就直接/upload/1.png就ok了。
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/upload/**")
                .addResourceLocations("file:"+System.getProperty("user.dir")+"/upload/");
        }
    
    }

    表情包

    自己手动下载,emoji 表情包,放到图片路径下:

    修改editormd.js文件

    // Emoji graphics files url path
    editormd.emoji     = {
        path  : "../editormd/plugins/emoji-dialog/emoji/",
        ext   : ".png"
    };

    文章展示

    1、Controller 中增加方法

    @GetMapping("/{id}")
    public String show(@PathVariable("id") int id,Model model){
        Article article = articleMapper.getArticleById(id);
        model.addAttribute("article",article);
        return "article";
    }

    2、页面 article.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
        <title th:text="${article.title}"></title>
    </head>
    <body>
    
    <div>
        <!--文章头部信息:标题,作者,最后更新日期,导航-->
        <h2 style="margin: auto 0" th:text="${article.title}"></h2>
        作者:<span style="float: left" th:text="${article.author}"></span>
        <!--文章主体内容-->
        <div id="doc-content">
            <textarea style="display:none;" placeholder="markdown" th:text="${article.content}"></textarea>
        </div>
    
    </div>
    
    <link rel="stylesheet" th:href="@{/editormd/css/editormd.preview.css}" />
    <script th:src="@{/editormd/lib/jquery.min.js}"></script>
    <script th:src="@{/editormd/lib/marked.min.js}"></script>
    <script th:src="@{/editormd/lib/prettify.min.js}"></script>
    <script th:src="@{/editormd/lib/raphael.min.js}"></script>
    <script th:src="@{/editormd/lib/underscore.min.js}"></script>
    <script th:src="@{/editormd/lib/sequence-diagram.min.js}"></script>
    <script th:src="@{/editormd/lib/flowchart.min.js}"></script>
    <script th:src="@{/editormd/lib/jquery.flowchart.min.js}"></script>
    <script th:src="@{/editormd/editormd.js}"></script>
    
    <script type="text/javascript">
        var testEditor;
        $(function () {
            testEditor = editormd.markdownToHTML("doc-content", {//注意:这里是上面DIV的id
                htmlDecode: "style,script,iframe",
                emoji: true,
                taskList: true,
                tocm: true,
                tex: true, // 默认不解析
                flowChart: true, // 默认不解析
                sequenceDiagram: true, // 默认不解析
                codeFold: true
            });});
    </script>
    </body>
    </html>

    重启项目,访问进行测试!大功告成!

    展开全文
  • 笔者平时写文章使用的都是,但是发布的时候就会遇到一些平台不支持的情况,重排是不可能重排的,所以都会使用一些转富文本的工具,比如markdown-nice,用的多了就会好奇是怎么实现的,于是就有了本篇文章。...
  • 1.运行环境不同,网页在浏览器中运行,小程序在微信中运行 2、 开发模式不同 网页是浏览器加编译器开发 小程序是在微信开发者工具中创建和配置小程序项目 3、api不同。小程序无法调用浏览器BOM和DOM提供的api。但是...
  • hello,大家好,这里是「CSDN产品周报」第26期。本次更新主要涉及首页和博客,欢迎大家详细了解和使用。 一、首页导航频道优化 ... ...1、博客首页导航交互及 UI 优化...为进一步提高博文发布效率,我们富文本编辑器新增了
  • 简易富文本编辑器

    2017-07-19 11:13:33
    运营同事在微信公众号发布文章时,常常按照以下步骤操作: 打开“秀米”网 =》 挑选模版 =》 编辑好内容 =》 一键复制代码 打开微信公众平台 =》 新建文章 =》 粘贴到编辑器里 =》 确认发布 紧接着,这个工作多了...
  • 大厂技术坚持周更精选好文最近搞各种编辑器,也涉及到了富文本编辑器,prosemirror[1]是当前非常流行的富文本编辑器,因此希望通过剖析其实现原理,来窥探编辑器的架构设计。背景prosemirror 的官网提供了很多的 ...
  • 这 markdown 编辑器爱了爱了
  • 前端与移动开发----微信小程序----小程序(一)

    千次阅读 多人点赞 2021-04-17 09:50:28
    微信小程序
  • Markdown编辑器推荐

    2021-10-15 16:31:23
    Markdown编辑器推荐 Markdown Markdown是一种轻量级标记语言,排版语法简洁,让人们更多地关注内容本身而非排版。它使用易读易写的纯文本格式编写文档,可与HTML混编,可导出 HTML、PDF 以及本身的 .md 格式的文件。...
  • 这个神奇的国产软件,你以为他是文本编辑器,其实它是一个 MySQL 客户端;你以为它是 MySQL 客户端,其实它是一个 Redis 客户端;你以为它是一个 Redis 客户端,其实它是...
  • 大学的时候,坊间对那些编程高手有一个令人向往的传说,大概说的是大神们能够直接使用text纯文本写代码。觉得这种级别的境界特别高大上特别有逼格。自己用eclipse,vs这些带有代码补全功能的IDE就感觉有点low。于是...
  • 希望通过阅读本文,对于想利用WordPress REST API 开发微信小程序的开发者,能有所帮助,而不是如本文标题所说的,看了文章反而想放弃了。
  • 使用 wxParser 插件并配合富文本编辑器,可以很方便地开发内容展示类小程序。 实时数据库 实时数据库是基于 WebSocket 实现客户端和服务端的实时双向通信,在云端数据发生变化时马上通知所有客户端来同步数据。通过...
  • 网络请求目前没有同步版本。 微信小程序常见FAQ(17.7.31-17.8.6) Q:小程序缓存机制是怎么样的? A:小程序发版,客户端先用之前的包打开,异步更新好。下次重新打开才是用新包。7天之内不使用的小程序...
  • C#微信开发

    千次阅读 2017-06-05 20:50:30
    C#开发微信门户及应用教程   作者:伍华聪   C#开发微信门户及应用(1)--开始使用微信接口 6 1、微信账号 6 2、微信菜单定义 7 3、接入微信的链接处理 8 4、使用开发方式创建菜单 14 5、我创建的菜单案例 17 C#...
  • 微信小程序
  • 公式等图片等富文本在线一些程序

    千次阅读 2018-03-06 06:46:53
    https://github.com/fraywing/textAngular/  一个angular directive Wysiwyg style 前端编辑器,可以用于定制化开发,增加数学表达式创建工具栏 http://www.codecogs.com/latex/eqneditor.php 使用latex的语法而...
  • 微信小程序开源项目

    千次阅读 2020-02-23 21:59:49
    微信小应用示例代码(phodal/weapp-quick) 源码链接:https://github.com/phodal/weapp-quick 微信小应用地图定位demo(giscafer/wechat-weapp-mapdemo) 源码链接:...
  • 公司的管理后台有集成的富文本编辑器,运营同学可以在后台编辑文章发布到我们的服务器上,然后在客户端微信上可以作为一些内容的点击链接或者直接访问来显示出编辑的效果。但是我们的编辑器排版资源不够丰富,而且大...
  • 微信小程序入门篇

    千次阅读 2021-02-13 20:34:59
    推广app或者公众号的成本太高; 开发适配成本低;(以前开发app需要去适配不同的手机型号,十分繁琐,而开发小程序只需要按照小程序开发文档开发即可,微信会帮我们做好适配工作) 容易小规模试错,便于快速迭代; 跨...
  • 文本编辑器 使用笔记 安装离线版本,自动安装MS Word插件; 通过插件,将Zotero笔记,插入到Word文档中。 按照指定规范添加参考文献。 选择笔记 插入后 其他 支持本地安装,和离线导出。 支持Web使用,和内容同步。...
  • 微信小程序入门笔记(一)

    千次阅读 2020-12-25 22:45:24
    曾命名为“官号平台”、“媒体平台”、微信公众号,最终定位为“公众平台”,无疑让我们看到一个微信对后续更大的期望。 利用公众账号平台进行自媒体活动,简单来说就是进行一对多的媒体性行为活动,如商家通过申请...
  • 学习记录-微信小程序

    千次阅读 2019-08-13 12:25:33
    } 3)内联样式 4)选择 用于选择目标元素的样式的模式 优先级 按规定分配给不同选择的权重,通过优先级判断页面元素应用那个哪个样式模式 3.JavaScript 概念:一种轻量级,解释型的、面向对象的头等函数语言,是...
  • 微信小程序常见FAQ (17.8.21-17.8.27)

    千次阅读 2018-06-15 11:06:58
    Q:1.5版本基础库的小程序出现了image bindload事件响应两次的问题。A:你好,感谢反馈,我们会尽快进行修复,敬请关注。Q:地图里marker的callout在...Q:新版微信开发者工具,tabBar选中字体颜色不对。A:收到,我...
  • 为什么要学习 Markdown?究竟有什么用?

    千次阅读 多人点赞 2020-02-09 17:20:26
    微信公众号:杰哥的IT之旅(ID:Jake_Internet) 一、什么是 Markdown? Markdown 是一种轻量级标记语言,创始人是约翰·格鲁伯(John Gruber)。允许人们使用易读易写的纯文本格式编写文档,可以导出 HTML 、Word、...
  • 微信小程序常见面试题总结

    千次阅读 多人点赞 2020-01-10 15:26:03
    为媒体和个人提供一种新的信息传播方式,主要功能是在微信侧给用户传达资讯。一天群发1次,显示在订阅号文件内,高级接口有限制 服务号: 为企业和组织提供更强大的业务服务与用户管理能力,主要偏向服务类交互。不...
  • 目前CSDN支持富文本和markdown两种编辑格式,由于使用富文本编辑模式除了要考虑文章内容外,还要顾及到文章的排版格式,而markdown就没有排版这种烦恼,因为markdown的文章格式是固定好的 下面是我之前写的markdown...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 445
精华内容 178
关键字:

微信公众号富文本编辑器同步

友情链接: AVCap.zip