一、富文本编辑器

富文本编辑器也就是所见即所得的在线编辑器,现在应用非常广泛,基本上复杂一些的内容发布,无论是论坛、博客等等都得用到。

各种各样的富文本编辑器也是很多,比如 kindeditor (貌似已经GG了)、Ueditor(现在基本上使用的很多),等等。

我不确定 markdown 是否属于富文本编辑器一类,只不过像是搞IT的很多都喜欢用markdown,当然专业的写作肯定是用富文本编辑器的多了。

而且很多富文本编辑器都支持markdown语法。

二、使用 javascript 构建富文本编辑器的核心

1、 div 的 contentEditable 属性

最早是加载 iframe 来完成的,使用 iframe 的加载,需要加载额外的一个 html 文件,做到在窗口中所见即所得。

实际上编辑的是 iframe 中的 html 文件内容。

现在基本都会直接使用 div 的 contentEditable 属性,设置了之后,就能对 div 进行内容的编辑,从而做到所见即所得。

2、对 html 的编辑通过 execCommand

富文本编辑器 无非就是不需要用户去编辑 html , 写html代码而已,实际上就是通过按钮来操作。

最麻烦的方法,无非就是用 createRange();搞一个选区,对选取的 html 进行操作。

execCommand 显得更加的强大,执行一条命令即可完成

// 将选中的文字字号变成7 
document.execCommand("fontsize",false,"7");

具体的命令列表就不列举了

三、使用 javascript 构建一个富文本编辑器

1、效果

2-1.jpg

2、代码

1)css 样式

        .rich-edit-box {
            width: 800px;
        }

        .rich-edit-head {
            width: 100%;
        }

        .rich-edit-head>.edit-btn {
            background-color: #ffffff;
            color: #000000;
            border: solid 1px #000000;
            border-bottom: 0px;
            padding: 5px;
            cursor: pointer;
        }

        .rich-edit-head>.edit-btn:hover {
            background-color: #000000;
            color: #fff;
            border: solid 1px #aaaaaa;
            border-bottom: 0px;
        }

        .rich-edit-content {
            border: solid 1px #000000;
            width: 100%;
            min-height: 500px;
            padding: 10px;
        }

2)html 给一个div

    <h1>富文本编辑器</h1>
    <hr>
    <div id="richEditBox">
        
    </div>

3)使用 javascript 创建富文本编辑器


    window.onload = function () {
        RichEdit("richEditBox");
    }
    var RichEdit = function (boxId) {
        var richEditBox = document.getElementById(boxId),
            
            editHtml= '<div class="rich-edit-box">'+
            '<div class="rich-edit-head">'+
            '    <select class="edit-btn edit-select" name="formatblock">'+
            '        <option value="<span>">标题</option>'+
            '        <option value="<h1>">H1</option> '+
            '        <option value="<h2>">H2</option>'+
            '        <option value="<h3>">H3</option>'+
            '        <option value="<h4>">H4</option>'+
            '        <option value="<h5>">H5</option>'+
            '        <option value="<h6>">H6</option>'+
            '    </select>'+
            '    <select class="edit-btn edit-select" name="fontsize">'+
            '        <option value="">字号</option>'+
            '        <option value="7">7</option> '+
            '        <option value="6">6</option>'+
            '        <option value="5">5</option>'+
            '        <option value="4">4</option>'+
            '        <option value="3">3</option>'+
            '        <option value="2">2</option>'+
            '        <option value="1">1</option>'+
            '    </select>'+
                '<select class="edit-btn edit-select" name="forecolor">'+
                    '<option value="black">字体颜色</option>'+
                    '<option value="red">红色</option> '+
                    '<option value="green">绿色</option>'+
                    '<option value="blue">蓝色</option>'+
                   ' <option value="yellow">黄色</option>'+
                    '<option value="white">白色</option>'+
                    '<option value="black">黑色</option>'+
                '</select>'+
                '<button type="button" class="edit-btn edit-btn-html" name="bold" value="null">粗体</button>'+
                '<button type="button" class="edit-btn edit-btn-html" name="italic" value="null">斜体</button>'+
                '<button type="button" class="edit-btn edit-btn-html" name="delete" value="null">删除</button>'+
                '<button type="button" class="edit-btn edit-btn-html" name="underline" value="null">下划线</button>'+
               ' <button type="button" class="edit-btn edit-btn-link" name="createlink" value="null">链接(a)</button>'+
                '<button type="button" class="edit-btn edit-btn-html" name="unlink" value="null">删除链接</button>'+
                '<button type="button" class="edit-btn edit-btn-html" name="indent" value="null">右缩进</button>'+
                '<button type="button" class="edit-btn edit-btn-html" name="outdent" value="null">左缩进</button>'+
                '<button type="button" class="edit-btn edit-btn-html" name="justifycenter" value="null">居中</button>'+
                '<button type="button" class="edit-btn edit-btn-html" name="justifyleft" value="null">左对齐</button>'+
            '</div>'+
            '<div class="rich-edit-content">'+
                '请输入你的内容...'+
            '</div>'+
        '</div>'; 
        // 输入html
        richEditBox.innerHTML = editHtml;
        var editSelectList = richEditBox.querySelectorAll(".edit-select");
            editBtnLink = richEditBox.querySelector(".edit-btn-link"),
            richEditContent = richEditBox.querySelector(".rich-edit-content"),
            editBtnHtmlList = richEditBox.querySelectorAll(".edit-btn-html");
        // 开启编辑模式
        richEditContent.setAttribute("contentEditable", true);
        // 自动焦点
        richEditContent.focus();
        // 给每个 formatblock btn添加事件
        for (var i = 0, len = editBtnHtmlList.length; i < len; i++) {
            editBtnHtmlList[i].onclick = function (event) {
                var target = event.target;
                document.execCommand(target.name, false, target.value);
            }
        }
        // 给每个 formatblock select 添加事件
        for (var i = 0, len = editSelectList.length; i < len; i++) {
            editSelectList[i].onchange = function (event) {
                var target = event.target;
                document.execCommand(target.name, false, target.value);
            }
        }
        // link事件
        editBtnLink.onclick = function (event) {
            var res = window.prompt("Input link's URL");
            return (!res || res.length == 0) ? false : document.execCommand(event.target.name, false, res);
        }
    };

四、问题

这只是一个很简单很简单的富文本编辑器的示例,还有很多东西没做

  • 比如 h1 可以显示字体的大小在 select 上
  • 颜色也可以显示出来
  • 图片上传插入
  • 直接编辑html(有html代码和预览两部分组成)
  • 列表
  • 代码
  • ......

同样的,也没有做到光标监听,光标监听应当时刻注意当前行的 html 解析,从而显示当前使用的富文本。

将 编辑器的内容写入表单字段,可以在提交或者保存之前,把内容(html代码)传入隐藏的 textarea 中,或者是时刻监听时刻写入。