我的富文本编辑器

先截个图看看效果:


前面讲过execCommand以及光标选区操作,富文本中核心应用便是如此。

大体思路就是根据浏览器兼容性利用execCommand以及选区去在可编辑话的iframe中进行插入代码以及样式。我们来一步步实现:

第一步:首先建立一个html文档
<body>
    <div id='container'>
        <div id="editor">
          <span class=" editStr curr0" title='加粗' unselectable='on' range='bold'></span>
          <span class="editStr curr1" title='斜体'  unselectable='on' range='italic'></span>
          <span class="editStr curr2" title='下划' unselectable='on' range='underline'></span>         
          <select title='fontname'>
            <option >字体样式</option>
            <option value="SimSun">宋体</option>
            <option value="LiSu">隶书</option>
            <option value="KaiTi_GB2312">楷体</option>
            <option value="YouYuan">幼圆</option>
            <option value="SimHei">黑体</option>
            <option value="Microsoft YaHei">雅黑</option>
            <option value="Comic Sans MS">Comic Sans MS</option>
          </select>
          <select title='fontsize'>
            <option value="0">字体大小</option>
            <option value="1">很小</option>
            <option value="2">小</option>
            <option value="3">中</option>
            <option value="4">大</option>
            <option value="5">很大</option>
            <option value="6">特大</option>
          </select>
          <select title='forecolor'>
             <option >字体颜色</option>
            <option style="color:#000000" value="#000000">■■</option>
            <option style="color:#990" value="#990">■■</option>
            <option style="color:#cc6600" value="#cc6600">■■</option>
            <option style="color:#cc9933" value="#cc9933">■■</option>
            <option style="color:#999900" value="#999900">■■</option>
            <option style="color:#009900" value="#009900">■■</option>
            <option style="color:#3333ff" value="#3333ff">■■</option>
            <option style="color:#6600cc" value="#6600cc">■■</option>
            <option style="color:#993399" value="#993399">■■</option>
          </select>
          <select title='backcolor'>
            <option >背景颜色</option>
            <option style="color:#000000" value="#000000">■■</option>
            <option style="color:#990" value="#990">■■</option>
            <option style="color:#cc6600" value="#cc6600">■■</option>
            <option style="color:#cc9933" value="#cc9933">■■</option>
            <option style="color:#999900" value="#999900">■■</option>
            <option style="color:#009900" value="#009900">■■</option>
            <option style="color:#3333ff" value="#3333ff">■■</option>
            <option style="color:#6600cc" value="#6600cc">■■</option>
            <option style="color:#993399" value="#993399">■■</option>
          </select>
          <span class="editStr curr3"title='居中'  unselectable='on' range='justifycenter'></span>
          <span class="editStr curr4"title='居左' unselectable='on'  range='justifyleft'></span>
          <span class="editStr curr5"title='居右' unselectable='on' range='justifyright'></span>
          <span class="editStr curr6"title='减少缩进' unselectable='on' range='outdent'></span>
          <span class="editStr curr7"title='增加缩进' unselectable='on' range='indent'></span>
          <span class="editStr curr8"title='无序' unselectable='on' range='insertunorderedlist'></span>
          <span class="editStr curr9"title='有序' unselectable='on' range='insertorderedlist'></span>
          <span class="editStr curr12"title='表格' unselectable='on' range='table'></span>
          <span class="editStr curr10"title='超链接' unselectable='on' range='createlink'></span>
          <span class="editStr curr11"title='图片' unselectable='on' range='insertimage'></span>
          <span class="editStr curr13"title='表情' unselectable='on' range='faceImage'></span>
          <span class="checkEdit"title='html' unselectable='on' range='html'><input type='checkBox' id='checkEdit'><p >查看源码</p></span>
        </div>
        <textarea id='myTextArea' disabled></textarea>
    </div>
  </body>
  其中span类型的都把值放入自定义属性range中,select类型例如颜色字体放入select中值为value。以备后用.

  第二步:

  我们新建iframe以及将textArea隐藏,便于在源码以及编辑进行切换。iframe以及div都是可以操作的,在这里我们选取iframe并将其designMode属性设为on即开启编辑模式,

  代码如下:

  var editor = document.getElementById("editor");
            var spans = editor.getElementsByTagName("span");
            var selects = editor.getElementsByTagName("select");
            var textarea = document.getElementById("myTextArea");
            textarea.style.display = "none";
            var iframe = document.createElement("iframe");
            iframe.style.width = "1198px";
            iframe.style.height = "380px";
            iframe.frameBorder=0;
            iframe.scrolling="no";
            iframe.style.border='0px';
            textarea.parentNode.insertBefore(iframe,textarea);
            var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
            var iframeWindow=iframe.contentWindow;
            iframeDocument.designMode = "on";
            iframeDocument.write('<html><head></head><body ></body></html>');
            var editMode=true;
            var faceCreater,tableCreator;
    第三步:

之后我们循环页面的span以及select,先将这些execCommand支持command加入我们的富文本编辑器中,只需要iframeDocument.execCommand(command,false,value)即可,

对于span来说value值没有可选性就置为空,对于html编辑状态源码之间切换以及table插入以及表情插入我们另说。先看基本功能。这里没有什么需要着重注意的,直接看代码:

    for(var i = 0,l= spans.length;i<l;i++){
                spans[i].onclick = (function(i){
                    var command=spans[i].getAttribute("range");
                    return function(){
                       if(command == 'createlink' || command == 'insertimage'){
                            var value =command=='createlink'? prompt('请输入超链接:', 'http://'):prompt('请选择图片:', 'http://');
                            iframeDocument.execCommand(command,false,value);
                        }else if(command=='html'){
                           if(editMode){//切换到textarea
                                iframe.style.display = "none";
                                textarea.style.display = "block";
                                textarea.value = iframeDocument.body.innerHTML;
                                //textarea.focus();
                                editMode = false;
                                document.getElementById('checkEdit').checked=true;
                            }else{//切换到iframe
                                iframe.style.display = "block";
                                textarea.style.display = "none";
                                iframeDocument.body.innerHTML = textarea.value;
                                iframe.contentWindow.focus();
                                editMode = true;
                                document.getElementById('checkEdit').checked=false;
                            }
                        }
                        else if(command=='table'){
                            //稍后另说
                        }
                        else if(command=='faceImage'){
                            
                        }
                        else{
                            iframeDocument.execCommand(command,false,'');
                        }
                    }
                })(i);
            };
            for(i=0,l=selects.length;i<l;i++){
                selects[i].onchange = (function(i){
                var select = selects[i];
                return function(){
                    var command = select.getAttribute("title"),
                    value = select.options[select.selectedIndex].value;
                    if(command == 'backcolor' && window.navigator.userAgent.toLowerCase().indexOf("Firefox")){
                        iframeDocument.execCommand('hilitecolor',false,value);
                    }else{
                        iframeDocument.execCommand(command,false,value);
                    };
                }
              })(i);
            };
    补充一句这里的背景色在火狐中默认将背景色填充满整个iframe,所以做一下兼容处理。

    第四步:

    我们来额外处理table,由于execCommand中没有对table的支持,所以我们需要手动去实现:

    实现思路我们首先要建立一个可以选择table的列以及行的选择框

    1.

建立弹出层以供选择创建行列数:

            tableCreator = document.createElement('div');

            tableCreator.className = 'tablecreator';

            editor.appendChild(tableCreator);

            tableCreator.innerHTML = editTable();//生成弹出层内容代码函数

            tableCreator.style.display='none';                           

    2.

    生成完之后样式如下图:

   

    自定义行列之后点击确定

    html = createTable(rows, cols, width);//创建自定义表格

    insertHtml(html);

    tableCreator.style.display = "none";

    3.

    最重要一步就是把生成表格置到我们的编辑器中也就是上述的insertHtml方法,这个方法接受的一个参数就是根据我们自定义的行列所生成的表格。

    function insertHtml(html){

            iframe.contentWindow.focus();

            if(isIe){
               if(lessThenIE9){

                    iframeDocument.selection.createRange().pasteHTML(html);
                }

                else{

    iframeDocument.selection.createRange().pasteHTML(html);

                    //解决iframe无光标

                    var span=iframeDocument.createElement('span');

                    span.innerHTML='&nbsp';

                    iframeDocument.body.appendChild(span);

                }

            }else{

                iframeDocument.execCommand('inserthtml',false,html);

                iframe.contentWindow.focus();

            }

        }

首先我们先对iframe获得焦点,对于ie来说以下不支持execCommand的inserthtml,不过可以根据ie特有的document.selection.createRange()选区操作去创建html(忘记的看这里),

并且利用其pasteHTML方法去方便的创建(不得不说其实ie还是有很多优秀的前瞻性的值得借鉴地方),

对于非ie浏览器就应用execCommand即可实现。

经过测试对于ie9,10来说生成表格之后都有一个bug,就是生成完表格之后光标无法从表格内部移除,也就使得无法继续对iframe进行富文本编辑。


这个里面的光标是无法移出来的。

为解决这个问题,我生成了一个空的span,并将其插入到iframe中,这样一来默认生成完html之后光标会落到最后,以解决iframe焦点问题。

这样以来整个流程就跑通了,并且任何浏览器都会兼容。

对于表情插入来说跟table插入是大同小异的,只不过插入的是一个带有选中表情图片url的img元素而已,在此不再赘述。

下载完整代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值