• 如何做一个富文本编辑器


    很久以前就想做一个富文本编辑器,但是感觉比较难,一直没有实现。直到了解了html5的contenteditable属性可以设置一个div为可编辑状态,利用这个特性做富文本编辑器就比较简单了 

    首先 认识一下 contenteditable 它是一个属性 可以这样使一个DIV的编辑状态被激活

    <div contenteditable="true"></div>

    然后这个div就可以被编辑了 而我们要想获得它的html源码可以使用innerHTML来取得 


    举个例子如下:

    如果我们想在页面上修改CSS属性值而让它所控制的元素实时变化,就可以这样做:

    先在head里的style设置body里面的style元素是显示的 这样我们才可以编辑 style元素放在body区域默认是不显示的

    <style>
            body style{
                display:block;
                padding:0.6em 0.8em;
                border:1px dashed #ccc;
                background-color:#f5f5f5;
                color:#000;
                font-family:Monaco, monospace;
                font-size:12px;
                white-space:pre-wrap;
                word-wrap:break-word;
            }
        </style>

    这样我们body里的style元素就显示出来了

    然后我们在body里面定义style 可能像下面这样 设置它为可编辑的

    <body>
    <style contenteditable="true">
        .main{
            background: #444;
            font-size: 2em;
            border: 1px solid #0f0;
            border-radius: 3px;
            color: #46b8da;
        }
    </style>

    在页面上跑一下 是不是发现 所有使用main class的元素都会随着你的CSS值改变而实时改变


    言归正传 继续看富文本编辑器如何实现 

    想象一下我们在富文本编辑器中如何改变文本的style 首先第一步就是如何取得当前选中的内容

    如何获得选择文字 首先应该了解一下Range对象

    所谓"Range",是指HTML文档中任意一段内容。一个Range的起始点和结束点位置任意,甚至起始点和结束点可以是一样的(也就是空Range)。最常见的Range是用户文本选择范围(user text selection)。当用户选择了页面上的某一段文字后,你就可以把这个选择转为Range。当然,你也可以直接用程序定义Range

    而且Range也有三种版本 W3C Mozilla Microsoft

    • W3C Range对象是唯一官方指定。基本上其是将Range作为包含DOM的文档片段。
    • Mozilla Selection对象显得有些多余,其存在是为了向后兼容Netscape 4。其类似于W3C Range对象,也是基于DOM树的。
    • Microsoft Text Range因为其是基于字符串的。事实上,Text Range包含的字符串是很难一下子跳变成DOM节点的。

    具体也就不解释了 直接看代码吧 如何获得选中文字

    var userSelection;
        if (window.getSelection) { //现代浏览器
            userSelection = window.getSelection();
        } else if (document.selection) { //IE浏览器
            userSelection = document.selection.createRange();
        }

    随便console.log(userSelection)一下 就会发现选中的内容真的被打印出来了

    接下就是如何设置选中文本的样式了,这里要掌握的是 document.execCommand()方法处理Html数据

    document.execCommand()方法处理Html数据时常用语法格式如下: 
    复制内容到剪贴板 
    代码: 
    document.execCommand(sCommand[,交互方式, 动态参数]) 
    
    其中:sCommand为指令参数(如下例中的”2D-Position”),交互方式参数如果是true的话将显示对话框,如果为false的话,则不显示对话框(下例中的”false”即表示不显示对话框),动态参数一般为一可用值或属性值(如下例中的”true”)。 
    
    document.execCommand(”2D-Position”,”false”,”true”); 
    
    调用execCommand()可以实现浏览器菜单的很多功能. 如保存文件,打开新文件,撤消、重做操作…等等. 有了这个方法,就可以很容易的实现网页中的文本编辑器. 
    
    如果灵活运用,可以很好的辅助我们完成各种项目. 
    
    下面列出的是指令参数及意义 
    
    //相当于单击文件中的打开按钮 
    document.execCommand(”Open”); 
    
    //将当前页面另存为 
    document.execCommand(”SaveAs”); 
    
    //剪贴选中的文字到剪贴板; 
    document.execCommand(”Cut”,”false”,null); 
    
    //删除选中的文字; 
    document.execCommand(”Delete”,”false”,null); 
    
    //改变选中区域的字体; 
    document.execCommand(”FontName”,”false”,sFontName); 
    
    //改变选中区域的字体大小; 
    document.execCommand(”FontSize”,”false”,sSize|iSize); 
    
    //设置前景颜色; 
    document.execCommand(”ForeColor”,”false”,sColor); 
    
    //使绝对定位的对象可直接拖动; 
    document.execCommand(”2D-Position”,”false”,”true”); 
    
    //使对象定位变成绝对定位; 
    document.execCommand(”AbsolutePosition”,”false”,”true”); 
    
    //设置背景颜色; 
    document.execCommand(”BackColor”,”false”,sColor); 
    
    //使选中区域的文字加粗; 
    document.execCommand(”Bold”,”false”,null); 
    
    //复制选中的文字到剪贴板; 
    document.execCommand(”Copy”,”false”,null); 
    
    //设置指定锚点为书签; 
    document.execCommand(”CreateBookmark”,”false”,sAnchorName); 
    
    //将选中文本变成超连接,若第二个参数为true,会出现参数设置对话框; 
    document.execCommand(”CreateLink”,”false”,sLinkURL); 
    
    //设置当前块的标签名; 
    document.execCommand(”FormatBlock”,”false”,sTagName); 
    
    //相当于单击文件中的打开按钮 
    document.execCommand(”Open”); 
    
    //将当前页面另存为 
    document.execCommand(”SaveAs”); 
    
    //剪贴选中的文字到剪贴板; 
    document.execCommand(”Cut”,”false”,null); 
    
    //删除选中的文字; 
    document.execCommand(”Delete”,”false”,null); 
    
    //改变选中区域的字体; 
    document.execCommand(”FontName”,”false”,sFontName); 
    
    //改变选中区域的字体大小; 
    document.execCommand(”FontSize”,”false”,sSize|iSize); 
    
    //设置前景颜色; 
    document.execCommand(”ForeColor”,”false”,sColor); 
    
    //使绝对定位的对象可直接拖动; 
    document.execCommand(”2D-Position”,”false”,”true”); 
    
    //使对象定位变成绝对定位; 
    document.execCommand(”AbsolutePosition”,”false”,”true”); 
    
    //设置背景颜色; 
    document.execCommand(”BackColor”,”false”,sColor); 
    
    //使选中区域的文字加粗; 
    document.execCommand(”Bold”,”false”,null); 
    
    //复制选中的文字到剪贴板; 
    document.execCommand(”Copy”,”false”,null); 
    
    //设置指定锚点为书签; 
    document.execCommand(”CreateBookmark”,”false”,sAnchorName); 
    
    //将选中文本变成超连接,若第二个参数为true,会出现参数设置对话框; 
    document.execCommand(”CreateLink”,”false”,sLinkURL); 
    
    //设置当前块的标签名; 
    document.execCommand(”FormatBlock”,”false”,sTagName); 

    这么一大堆的命令都可以使用 只需要调用它就可以动态修改文本的style了

    理论到这里就讲完了 接下来就是做了 我把写好的直接贴出来供参考吧 虽然写得不好 但是比较好懂

    如果你感觉我这样写不好 也可以看

    bootstrap-wysiwyg

    代码如下  为了方便全部在一个文件 你不能这么做

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="description" content="Rich Editor">
        <meta name="keywords" content="HTML5, CSS3,JavaScript,Bootstrap,jQuery,Web">
        <meta name="author" content="BaiQiang">
        <title>
            富文本编辑器
        </title>
    
        <!--为了方便开发我引入了bootstrap和jQuery 但它们和本项目没有任何必须依赖关系。
        你可以自己布局 也可以使用原生JavaScript操作-->
    
        <!-- 最新 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="http://cdn.bootcss.com/twitter-bootstrap/3.0.3/css/bootstrap.min.css">
    
        <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
        <script src="http://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
    
        <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
        <script src="http://cdn.bootcss.com/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script>
    
        <style contenteditable>
            #editor {
                max-height: 450px;
                height: 350px;
                background-color: white;
                border-collapse: separate;
                border: 1px solid rgb(204, 204, 204);
                padding: 4px;
                box-sizing: content-box;
                -webkit-box-shadow: rgba(0, 0, 0, 0.0745098) 0px 1px 1px 0px inset;
                box-shadow: rgba(0, 0, 0, 0.0745098) 0px 1px 1px 0px inset;
                border-top-right-radius: 3px;
                border-bottom-right-radius: 3px;
                border-bottom-left-radius: 3px;
                border-top-left-radius: 3px;
                overflow: scroll;
                outline: none;
            }
    
            .btn {
                font-family: "微软雅黑";
            }
        </style>
    </head>
    <body>
    <!--我需要一个工具栏-->
    <div class="btn-group">
        <button type="button" class="btn btn-deault">字体</button>
        <button type="button" class="btn btn-deault dropdown-toggle" data-toggle="dropdown">
            <span class="caret"></span>
            <span class="sr-only">Toggle Dropdown</span>
        </button>
        <ul class="dropdown-menu family" role="menu">
            <li><a href="#" data-edit="微软雅黑" style="font-family: '微软雅黑'">微软雅黑</a></li>
            <li><a href="#" data-edit="Serif" style="font-family: 'Serif'">Serif</a></li>
            <li><a href="#" data-edit="Courier New" style="font-family:'Courier New'">Courier New</a></li>
            <li><a href="#" data-edit="Lucida Sans" style="font-family: 'Lucida Sans'">Lucida Sans</a></li>
            <li><a href="#" data-edit="Times" style="font-family: Times">Times</a></li>
        </ul>
    </div>
    <div class="btn-group">
        <button type="button" class="btn btn-deault">大小</button>
        <button type="button" class="btn btn-deault dropdown-toggle" data-toggle="dropdown">
            <span class="caret"></span>
            <span class="sr-only">Toggle Dropdown</span>
        </button>
        <ul class="dropdown-menu size" role="menu">
            <li><a href="#" data-edit="7">H1</a></li>
            <li><a href="#" data-edit="5">H2</a></li>
            <li><a href="#" data-edit="4">H3</a></li>
            <li><a href="#" data-edit="3">H4</a></li>
            <li><a href="#" data-edit="2">H5</a></li>
            <li><a href="#" data-edit="1">H6</a></li>
        </ul>
    </div>
    <div class="btn-group style">
        <a href="#" class="btn btn-default" data-edit="bold">B</a>
        <a href="#" class="btn btn-default" data-edit="italic">I</a>
        <a href="#" class="btn btn-default" data-edit="strikethrough">S</a>
        <a href="#" class="btn btn-default" data-edit="underline">U</a>
    </div>
    
    <div class="btn-group list">
        <a href="#" class="btn btn-default" data-edit="InsertUnorderedList">UL</a>
        <a href="#" class="btn btn-default" data-edit="InsertOrderedList">OL</a>
        <a href="#" class="btn btn-default" data-edit="indent">TAB</a>
    </div>
    
    <div class="btn-group position">
        <a href="#" class="btn btn-default" data-edit="JustifyLeft">Left</a>
        <a href="#" class="btn btn-default" data-edit="JustifyCenter">Middle</a>
        <a href="#" class="btn btn-default" data-edit="JustifyRight">Right</a>
    </div>
    
    <div class="btn-group tool">
        <a href="#" class="btn btn-default" data-edit="SaveAs">Save</a>
        <a href="#" class="btn btn-default" data-edit="Copy">Copy</a>
        <a href="#" class="btn btn-default" data-edit="Delete">Delete</a>
    </div>
    <div class="btn-group">
        <button class="btn btn-default" id="clear">清理</button>
    </div>
    
    <div contenteditable="true" id="editor">
    
    </div>
    <script>
        var userSelection;
        if (window.getSelection) { //现代浏览器
            userSelection = window.getSelection();
        } else if (document.selection) { //IE浏览器
            userSelection = document.selection.createRange();
        }
        function editStyle(cmd, bool, value) {
            document.execCommand(cmd, bool, value);
        }
        $(function () {
            //editor use it's to clear html
            $.fn.cleanHtml = function () {
                var html = $(this).html();
                return html && html.replace(/(<br>|s|<div><br></div>|&nbsp;)*$/, '');
            };
            $(".size>li>a").click(function (e) {
                editStyle("FontSize", false, $(e.target).attr("data-edit"));
                e.preventDefault();
            });
            $(".family>li>a").click(function (e) {
                editStyle("FontName", false, $(e.target).attr("data-edit"));
                e.preventDefault();
            });
            $(".style>a").click(function (e) {
                editStyle($(e.target).attr("data-edit"), false);
                e.preventDefault();
            });
            $(".list>a").click(function (e) {
                editStyle($(e.target).attr("data-edit"), false);
                e.preventDefault();
            });
            $(".position>a").click(function (e) {
                editStyle($(e.target).attr("data-edit"), false);
                e.preventDefault();
            });
            $(".tool>a").click(function (e) {
                /*对于拷贝到剪切板和另存为网页只有IE支持*/
                editStyle($(e.target).attr("data-edit"), false);
                e.preventDefault();
            });
    
            $("#clear").click(function () {
                var html = $("#editor").cleanHtml();
                console.log(html);
            });
        });
    </script>
    </body>
    </html>

    最终效果图:

  • 相关阅读:
    为不喝的朋友准备的!如何委婉地拒绝劝酒
    参加Windows 7 成都软件俱乐部 发布活动
    解决CalendarExtender控件被遮挡的问题,并加上白色背景,以避免多层影响
    VS2008开发环境中容易遇到的3个问题之解决办法
    大开眼界的梦幻PHOTO
    51aspx是流氓!自动修改F5快捷键为打开它的站!
    ASP.NET DropDownList1 数据绑定的效率
    Repeater两层嵌套和三层嵌套repeater1_ItemDataBound绑定
    CuteEditor6.0使用配置心得体会
    谷歌Analytics添加到您的SharePoint 2010网站的2种方法
  • 原文地址:https://www.cnblogs.com/bq12345/p/3734756.html
Copyright © 2020-2023  润新知