为了账号安全,请及时绑定邮箱和手机立即绑定

Rich Text Editor实例

经过对网上一些常见的RichTextEditor(rte-light, jHTMLArea, NicEdit)的分析后,我决定自己来实现一个。
为的不是重新发明轮子,我也没想把这个做成一个完整的轮子,仅仅是为了学习内部的实现机制。

1. 使IFrame可编辑
为了达到对HTML的编辑,我们不可能在TextArea中完成,这就需要借助一个内嵌的IFrame。
第一个问题就是如何使IFrame(或者说一个页面)和Textarea具有类似的行为 - 可编辑。
下面我们对普通的IFrame和可编辑的IFrame进行比较:
正常的IFrame:
https://img1.sycdn.imooc.com//5aeab98c0001234403050157.jpg 
可编辑的IFrame: 
https://img1.sycdn.imooc.com//5aeab9930001131403050157.jpg 
相关代码:

<iframe id="iframe3"></iframe>
    <iframe id="iframe4"></iframe>
    
    $(function() {
        var iframe1 = $("#iframe1")[0].contentWindow.document;
        $(iframe1).find("body").html("<p>Hello <a href=\"http://www.google.com/\">Google</a></p>");
        var iframe2 = $("#iframe2")[0].contentWindow.document;
        iframe2.designMode = 'on';
        iframe2.open();
        iframe2.write("<p>Hello <a href=\"http://www.google.com/\">Google</a></p>");
        iframe2.close();
    });

2. 获取IFrame选中的值
IFrame可编辑,就意味着我们可以添加、删除、修改IFrame中的内容,
那么首要任务就是能通过编程的方式(JavaScript)获取选中的值。
下面一段程序兼容Firefox和IE:

<a id="selectedValue" href="javascript:;">获取当前选中区域</a>
    <iframe id="iframe4"></iframe>
    
    $(function() {
        var iwindow = $("#iframe2")[0].contentWindow;
        var idocument = iwindow.document;
        idocument.designMode = 'on';
        idocument.open();
        idocument.write("<p>Hello <a href=\"http://www.google.com/\">Google</a></p>");
        idocument.close();
        $("#selectedValue").click(function() {
            var range, html;
            if ($.browser.msie) {
                // IE下获取选中区域
                range = idocument.selection.createRange();
                // 选中区域的HTML
                html = range.htmlText;
            } else {
                // Firefox下获取选中区域
                range = iwindow.getSelection().getRangeAt(0);
                // 选中区域的HtmlFragment,我们需要一点小技巧来获取Html片段的内容
                var fragment = range.cloneContents();
                html = $("<div />").append($(fragment)).html();
            }
            alert(html);
        });
    });

如下图所示,选中的值为:
llo <a href="http://www.google.com/">Google</a> 
https://img1.sycdn.imooc.com//5aeab9c70001b8b903130174.jpg

更进一步,获取选中的纯文本值(去除所有HTML标签之后):

 $("#selectedValue").click(function() {
        var range, text;
        if ($.browser.msie) {
            // IE下获取选中区域
            range = idocument.selection.createRange();
            // 选中区域的text
            text = range.text;
        } else {
            // Firefox下获取选中区域
            range = iwindow.getSelection().getRangeAt(0);
            // 选中区域的HtmlFragment,我们需要一点小技巧来获取Html片段的内容
            var fragment = range.cloneContents();
            text = $("<div />").append($(fragment)).text();
        }
        // 按照上个例子中操作,获取的值为“llo Google”
        alert(text);
    });

3. 光标的位置
我们已经能够获取选中的值了,下面我们来尝试获取光标所在的位置。
注意:这里的光标位置指的是在纯文本中的位置(去除所有标签后)。

下面这段代码只适合IE,还没有找到Firefox下相应的解决办法。

var iwindow = $("#iframe2")[0].contentWindow;
    var idocument = iwindow.document;
    idocument.designMode = 'on';
    idocument.open();
    idocument.write("<p>Hello <a href=\"http://www.google.com/\">Google</a></p>");
    idocument.close();
    $("#selectedValue").click(function() {
        var range, cursorIndex = 0;
        // 必须的,否则有可能idocument获取不到焦点而报错
        iwindow.focus();
        if ($.browser.msie) {
            range = idocument.selection.createRange();
            range.setEndPoint("StartToStart", idocument.body.createTextRange());
            cursorIndex = range.text.length;
        } 
        alert(cursorIndex);
    });

这里的setEndPoint函数有点意思,比如我当前选中"Hello Google"中的"llo Go"。
setEndPoint的第一个参数"EndToStart"表示将range的结束位置(8)设为整个文本(idocument.body.createTextRange())的开始位置(0)。
此时range的开始位置(2),结束位置(0),也就是range此时代表的是0-2之间的字符串。
所以当前光标的位置(选中range的开始位置)就是range.text.length了。


4. 设置格式(粗体斜体)
其实大部分时候,我们不需要知道当前光标的位置,只需要对选中的字符串(range)设置格式就行了。
这一操作是通过调用document的execCommand函数来完成的。

<iframe id="iframe3"></iframe>
    <div id="Div1">
        <ul>
            <li class="bold"><a href="javascript:;">粗体</a></li>
            <li class="italic"><a href="javascript:;">斜体</a></li>
            <li class="underline"><a href="javascript:;">下划线</a></li>
            <li class="justifyleft"><a href="javascript:;">左对齐</a></li>
            <li class="justifycenter"><a href="javascript:;">居中</a></li>
            <li class="justifyright"><a href="javascript:;">右对齐</a></li>
        </ul>
    </div>
    var iwindow = $("#iframe2")[0].contentWindow;
    var idocument = iwindow.document;
    idocument.designMode = 'on';
    idocument.open();
    idocument.write("<p>Hello <a href=\"http://www.google.com/\">Google</a></p>");
    idocument.close();
    $("#jeditor li").click(function() {
        iwindow.focus();
        idocument.execCommand(this.className, false, null);
    });

https://img1.sycdn.imooc.com//5aeaba1200017c5603070186.jpg 

5. 插入链接与显示HTML代码
需要弹出对话框,让用户输入链接地址,其实可以通过execCommand的第三个参数做到这个效果:

<iframe id="iframe3" style="width: 300px; height: 200px;"></iframe>
    <textarea id="Textarea1" style="display: none; width: 300px; height: 200px;"></textarea>
    <br />
    <a id="A1" href="javascript:;">插入链接</a>
    <br />
    <a id="A2" href="javascript:;">显示HTML代码</a>
var iwindow = $("#iframe2")[0].contentWindow;
    var idocument = iwindow.document;
    idocument.designMode = 'on';
    idocument.open();
    idocument.write("<p>Hello <a href=\"http://www.google.com/\">Google</a></p>");
    idocument.close();
    $("#insertLink").click(function() {
        iwindow.focus();
        idocument.execCommand("createLink", false, prompt("请输入链接地址:", "http://"));
    });
    $("#showSource").toggle(function() {
        $("#source").val(idocument.body.innerHTML);
        $("#iframe2").hide();
        $("#source").show();
    }, function() {
        idocument.body.innerHTML = $("#source").val();
        $("#source").hide();
        $("#iframe2").show();
    });

https://img1.sycdn.imooc.com//5aeaba430001b01403120233.jpg 

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消