jquery插件 文本编辑器

参考文章:
http://www.cnblogs.com/lhb25/p/html5-wysisyg-inline-editor.html
http://guoliangheyuqin.iteye.com/blog/1676688
编写了一个简单的文本编辑器,使用document.execCommand命令对可编辑区域进行字体的加粗 斜体 对齐以及插入图片和超链接等操作。document.execCommand的用法可参考这篇文章

相关代码如下:
textEditor.js

(function(){
    var $options = null;
    var $containerObj = null;
    $.fn.textEditor = function(){
        var options;
        if(arguments != undefined ){
            if(arguments.length == 1 && typeof(arguments[0]) == 'object'){//选项参数 options = arguments[0]; }else if(arguments.length>0 && typeof(arguments[0]) == 'string'){//调用方法 dispatchMethod(arguments); }
        }

        $containerObj = $(this);
        var $defaults = {
            "undo":true,//默认显示
            "redo":true,//默认显示
            "repeat":true,
            "bold":true,
            "italic":true,
            "underline":true,
            "strikeThrough":true,//加删除线
            "justifyLeft":true,
            "justifyCenter":true,
            "justifyRight":true,
            "justifyFull":true,
            "indent":true,//缩进
            "outdent":true,//不缩进
            "insertUnorderedList":true,
            "insertOrderedList":true,
            "h1":true,
            "h2":true,
            "p":true,
            "subscript":true,   //下标?
            "superscript":true,  //上标?
            "removeFormat":true
            ,"fontSize":true
            ,"fontColor":true //字体颜色
            ,"hyperlink":true //超链接
            ,"picture":true // 图片
            ,"getHtmlText":true //获取html
        };
        $options = $.extend($defaults,options);

        if(!$containerObj.hasClass('customed-textEditor-cls')){
            $containerObj.addClass('customed-textEditor-cls');
        }


        var htmlStr = '<div class="content">'
                    + '<div class="container-fluid">'
                    + '<div id="pad-wrapper">'
                    + '<div id="editparent">'
                    + '<div class="span9 editControlsCls" style="padding:5px;">';
        //根据选项设置  添加格式按钮
        //撤销  重做
        htmlStr += '<div class="btn-group">';
        if($options.undo){
            htmlStr += "<a class='btn' title='撤销' data-role='undo' href='javascript:void(0);'>"
                    + "<i class='icon-undo'></i>"  
                    + "</a>";
        }
        if($options.redo){
            htmlStr += "<a class='btn' title='重做' data-role='redo' href='javascript:void(0);'><i class='icon-repeat'></i></a>";
        }
        htmlStr += '</div>';

        //20170327 add 
        //字体大小  字体颜色
        htmlStr += '<div class="btn-group">';
        if($options.fontSize){
            htmlStr += "<a id='fontSizeLink' class='btn' title='选择字体' data-role='fontSize' href='javascript:void(0);'><i class='icon-font'></i>"
                    + "</a>";
        }
        if($options.fontColor){//选择字体颜色
            htmlStr += "<a id='fontColorLink' class='btn' title='选择字体颜色' data-role='foreColor' href='javascript:void(0);'><i class='icon-table'></i>"
                    + "</a>";
        }
        htmlStr += '</div>';


        //粗体 斜体 下划线  删除线
        htmlStr += '<div class="btn-group">';
        if($options.bold){
            htmlStr += "<a class='btn' title='加粗' data-role='bold' href='javascript:void(0);'><b>Bold</b></a>";
        }
        if($options.italic){
            htmlStr += "<a class='btn' title='斜体' data-role='italic' href='javascript:void(0);'><em>Italic</em></a>";
        }
        if($options.underline){
            htmlStr += "<a class='btn' title='下划线' data-role='underline' href='javascript:void(0);'><u><b>U</b></u></a>";
        }
        if($options.strikeThrough){
            htmlStr += "<a class='btn' title='删除线' data-role='strikeThrough' href='javascript:void(0);'><strike>abc</strike></a>";
        }
        htmlStr += '</div>';

        //左端对齐  中间对齐  右端对齐  两端对齐
        htmlStr += '<div class="btn-group">';
        if($options.justifyLeft){
            htmlStr += "<a class='btn' title='左对齐' data-role='justifyLeft' href='javascript:void(0);'><i class='icon-align-left'></i></a>";
        }
        if($options.justifyCenter){
            htmlStr += "<a class='btn' title='居中' data-role='justifyCenter' href='javascript:void(0);'><i class='icon-align-center'></i></a>";
        }
        if($options.justifyRight){
            htmlStr += "<a class='btn' title='右对齐' data-role='justifyRight' href='javascript:void(0);'><i class='icon-align-right'></i></a>";
        }
        if($options.justifyFull){
            htmlStr += "<a class='btn' title='两端对齐' data-role='justifyFull' href='javascript:void(0);'><i class='icon-align-justify'></i></a>";
        }
        htmlStr += '</div>';

        //缩进  不缩进
        htmlStr += '<div class="btn-group">';
        if($options.indent){
            htmlStr += "<a class='btn' title='向右缩进' data-role='indent' href='javascript:void(0);'><i class='icon-indent-right'></i></a>";
        }
        if($options.outdent){
            htmlStr += "<a class='btn' title='向左缩进' data-role='outdent' href='javascript:void(0);'><i class='icon-indent-left'></i></a>";
        }
        htmlStr += '</div>';

        //插入有序列表 无序列表
        htmlStr += '<div class="btn-group">';
        if($options.insertUnorderedList){
            htmlStr += "<a class='btn' title='无序列表' data-role='insertUnorderedList' href='javascript:void(0);'><i class='icon-list-ul'></i></a>";
        }
        if($options.insertOrderedList){
            htmlStr += "<a class='btn' title='有序列表' data-role='insertOrderedList' href='javascript:void(0);'><i class='icon-list-ol'></i></a>";
        }
        htmlStr += '</div>';

        //插入 h1 h2 p
        htmlStr += '<div class="btn-group">';
        if($options.h1){
            htmlStr += "<a class='btn' title='一级标题' data-role='h1' href='javascript:void(0);'>h<sup>1</sup></a>";
        }
        if($options.h2){
            htmlStr += "<a class='btn' title='二级标题' data-role='h2' href='javascript:void(0);'>h<sup>2</sup></a>";
        }
        if($options.p){
            htmlStr += "<a class='btn' title='正文' data-role='p' href='javascript:void(0);'>p</a>";
        }
        htmlStr += '</div>';

        //20170328 插入图片和超链接
        htmlStr += '<div class="btn-group">';
        if($options.subscript){
            htmlStr += "<a class='btn' title='插入图片' data-role='insertImage' href='javascript:void(0);'><i class='icon-picture'></i></a>";
        }
        if($options.superscript){
            htmlStr += "<a class='btn' title='插入超链接' data-role='createLink' href='javascript:void(0);'><i class='icon-link'></i></a>";
        }
        htmlStr += '</div>';

        //插入上标 下标
        htmlStr += '<div class="btn-group">';
        if($options.subscript){
            htmlStr += "<a class='btn' title='下标' data-role='subscript' href='javascript:void(0);'><i class='icon-subscript'></i></a>";
        }
        if($options.superscript){
            htmlStr += "<a class='btn' title='上标' data-role='superscript' href='javascript:void(0);'><i class='icon-superscript'></i></a>";
        }
        htmlStr += '</div>';

        //清除格式 removeFormat
        htmlStr += '<div class="btn-group">';
        if($options.removeFormat){
            htmlStr += "<a class='btn' title='清除格式' data-role='removeFormat' href='javascript:void(0);'><i class='icon-check-empty'></i></a>";
        }
        //获取编辑器中html文本
        if($options.getHtmlText){
            htmlStr += "<a class='btn' title='获取HTML文本' data-role='getHtmlText' href='javascript:void(0);'><i class='icon-download-alt'></i></a>";
        }   
        htmlStr += '</div>';

        //编辑区域
        htmlStr += "<div class='editor-content-cls' contenteditable>"
                + "<h1>世界上最简单的文本编辑器!</h1>"
                + "<p>梦想天空博客关注<b>前端开发</b>技术,分享各种增强网站用户体验的 <b>jQuery</b> 插件,展示前沿的 <b>HTML5</b> 和 <b>CSS3</b> 技术应用,推荐优秀的网页设计案例,共享精美的设计素材和优秀的 <b>Web</b> 开发工具,希望这些精心整理的前端技术文章能够帮助到您。</p>"
                + "</div>";


        htmlStr += '</div></div></div></div></div>';

        //字体弹出框
        htmlStr += "<div class='fontSizeDlgCls' style='z-index:20000;display:none;'><ul><li><a href='javascript:void(0);' onclick='onclickFontSizeItem(this)'>1</a></li><li><a href='javascript:void(0);' onclick='onclickFontSizeItem(this)'>2</a></li>"
                + "<li><a href='javascript:void(0);' onclick='onclickFontSizeItem(this)'>3</a></li><li><a href='javascript:void(0);' onclick='onclickFontSizeItem(this)'>4</a></li>"
                + "<li><a href='javascript:void(0);' onclick='onclickFontSizeItem(this)'>5</a></li><li><a href='javascript:void(0);' onclick='onclickFontSizeItem(this)'>6</a></li>"
                +"<li><a href='javascript:void(0);' onclick='onclickFontSizeItem(this)'>7</a></li></ul></div>";

        //颜色表
        htmlStr += '<div class="colorTableDIVCls" style="z-index:20000;"></div>';

        /*
        //图片地址输入框
        htmlStr += '<div class="pictureInputDIVCls" style="z-index:20000;display:none;"><div class="tipCls">请输入图片地址:</div>'
                 + '<input class="inputTextCls"/>'
                 + '<div><button class="btn" onclick="submitPictureInput()" style="margin-left:100px;margin-right:30px;">确定</button><button class="btn" onclick="cancelPictureInput()">取消</button></div>'
                 + '</div>';    
        //超链接输入框
        htmlStr += '<div class="linkInputDIVCls" style="z-index:20000;position:fixed;top:0px;left:0px;width:100%;height:100%;display:none;"><div class="tipCls">请输入超链接地址:</div>'
                + '<input class="inputTextCls"/>'
                + '<button class="btn" onclick="submitLinkInput()" style="margin-left:100px;margin-right:30px;">确定</button><button class="btn" onclick="cancelLinkInput()">取消</button>'
                + '</div>';
        */

        $containerObj.html(htmlStr);

        //20170328 颜色表 
        var $colorTable = getColorTable('colorTableCls');
        $(".colorTableDIVCls").append($colorTable);
        $colorTable.onclick = setColor;//定义表格的点击事件
        $colorTable.style.display = "none";
        /*
         //表格颜色的点击事件
        $("table.colorTableCls td").click(function(){ //console.log("setColor evt: " ); //console.log(evt); var obj = this; if(obj.tagName == "TD" && obj.title){ console.log("obj.title: " + obj.title); console.log("obj.style.backgroundColor: " + obj.style.backgroundColor); var clickColor = obj.title; console.log(document); //this.style.display = "none"; document.designMode = "on"; document.contentEditable=true; window.focus(); alert(document.execCommand('foreColor',false, clickColor)); alert(document.execCommand('foreColor',false, "#f00")); } });
        */
        //定义编辑框各个按钮的点击事件
        $(".customed-textEditor-cls div.editControlsCls a ").click(function(e){ //console.log("$(this).data('role'): " + $(this).data('role')); //console.log("$(this).attr('data-role'): " + $(this).attr('data-role')); //console.log("$(this).prop('data-role'): " + $(this).prop('data-role'));//undefined switch($(this).data('role')){ //字号 case 'fontSize': var temp = getXY(document.getElementById("fontSizeLink")); var dlgLeft = temp.left + 2 +'px'; var dlgTop = temp.top + 30 + 'px';  $("div.fontSizeDlgCls").css('position', 'absolute'); $("div.fontSizeDlgCls").css('top', dlgTop); $("div.fontSizeDlgCls").css('left', dlgLeft); $("div.fontSizeDlgCls").css('display', ''); break; //字体颜色 case 'foreColor': var fontColorPosition = getXY(this); var colorTableLeft = fontColorPosition.left + 2 + 'px'; var colorTableTop = fontColorPosition.top + 30 + 'px'; $($colorTable).css('position', 'absolute'); $($colorTable).css('top', colorTableTop); $($colorTable).css('left', colorTableLeft); toggle($colorTable,"display","block","none"); break; case "insertImage": /*console.log($("a[data-role='insertImage']")[0]); var tempImage = getXY($("a[data-role='insertImage']")[0]); var dlgImageLeft = tempImage.left + 2 +'px'; var dlgImageTop = tempImage.top + 30 + 'px';  $("div.pictureInputDIVCls").css('position', 'absolute'); $("div.pictureInputDIVCls").css('top', dlgImageTop); $("div.pictureInputDIVCls").css('left', dlgImageLeft);  var inputObjPicture = $(".pictureInputDIVCls")[0]; $("div.pictureInputDIVCls input").val(""); toggle(inputObjPicture,"display","block","none");*/ var imageUrl = prompt("请输入图片地址!","http://"); var result = document.execCommand('insertImage', false, imageUrl); if(!result){ alert("图片插入失败"); } break;  case "createLink": /*var inputObjLink = $(".linkInputDIVCls")[0]; console.log(inputObjLink); toggle(inputObjLink,"display","block","none");*/ var linkUrl = prompt("请输入超链接地址!","http://"); var result = document.execCommand('createLink', false, linkUrl); if(!result){ alert("超链接插入失败"); } break;  case 'getHtmlText'://获取HTML文本 var htmlText = dispatchMethod(['getHtmlText']); alert("htmlText: " + htmlText); break; case 'h1': case 'h2': case 'p': //formatblock 添加html标签块 /* * 添加一个HTML块式标签在包含当前选择的行, 如果已经存在了, * 更换包含该行的块元素 (在 Firefox中, BLOCKQUOTE 是一个例外 -它将包含任何包含块元素). * 需要提供一个标签名称字符串作为参数。几乎所有的块样式标签都可以使用(例如. "H1", "P", "DL", "BLOCKQUOTE"). * (IE浏览器仅仅支持标题标签 H1 - H6, ADDRESS, 和 PRE,使用时还必须包含标签分隔符 < >, 例如 "<H1>".) * */ document.execCommand('formatBlock',false, '<' + $(this).data('role') + '>'); break; default: //执行命令 document.execCommand($(this).data('role'),false,null); break; } });//click

      /*  $("div.fontSizeDlgCls ul li").click(function(e){ var childrenArr = $(this).children(); var linkObj = childrenArr[0]; var selectedFontSize = linkObj.innerText; alert("selectedFontSize: " + selectedFontSize); //执行设置字号命令 //执行命令 document.execCommand('fontSize', false, selectedFontSize); //$("div.fontSizeDlgCls").css('display', 'none'); });*/

      //20170328 生成颜色表节点
        function getColorTable(classname){
            var table = document.createElement("table");
            //创建标题
            table.createCaption().appendChild(document.createTextNode("颜色表"));
            table.cellspacing = 0;
            table.cellpadding = 0;
            table.className = classname;

            var row = table.insertRow(0);
            for(var i=0; i<12; i++){ for(var j=0;j<18;j++){ var cell = row.insertCell(row.cells.length); //之前将setColor定义为td的onclick相应函数 但是不起作用 之后将setColor设置为<a>的onclick事件 cell.innerHTML= '<a style="width:12px;height:20px;display:inline-block;"' +'href="javascript:void(0);" onclick="setColor(this);">&nbsp;</a>'; var g = fixColor((j>6)?((j%6)*3):(j*3)); var b = fixColor((i>6)?((i%6)*3):(i*3)); var r = parseInt(j/6)*3; if(i>5) {r+=9;} r = fixColor(r); var color = '#' + r + g + b; cell.childNodes[0].style.backgroundColor = color; cell.childNodes[0].title = color; } row = table.insertRow(table.rows.length); } row = table.insertRow(table.rows.length); return table; } function fixColor(c){ var hexNum = [0,1,2,3,4,5,6,7,8,9,"A","B","C","D","E","F"]; c = parseInt(c); return hexNum[c]?hexNum[c]:0; } //切换元素css特性 function toggle(obj,css,val1,val2){ obj.style[css] = (obj.style[css] == val1 ? val2:val1); } //根据方法名调用相应方法 function dispatchMethod(arguments){ console.log(arguments); var method = arguments[0]; switch(method){ case "getHtmlText": var htmlText = $containerObj.find(".editor-content-cls").html(); return htmlText; break; default: throw new Error("方法【" + method + "】未定义!"); break; } } };//$.fn //20170302 返回obj位置 function getXY(obj){ //getBoundingClientRect()用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性 var rect = obj.getBoundingClientRect(); //获取滑动条位置 var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft; var isIE = !(!document.all)?2:0; var position = {}; position.left = rect.left - isIE + scrollLeft; position.top = rect.top - isIE + scrollTop; return position; } }()); //点击字号超链接 <a>响应事件 function onclickFontSizeItem(obj){ var selectedFontSize = obj.innerText; document.execCommand('fontSize', false, selectedFontSize); $("div.fontSizeDlgCls").css('display', 'none'); } function setColor(obj){ //console.log("setColor evt: " ); //console.log(evt); //evt = evt || window.event; //var obj = evt.target || evt.srcElement;//获取点击td //console.log(obj); if(obj.title){ console.log("obj.title: " + obj.title); console.log("obj.style.backgroundColor: " + obj.style.backgroundColor); var clickColor = obj.title;  document.execCommand('foreColor',false, clickColor); console.log("obj.parentNode.parentNode.parentNode: "); console.log(obj.parentNode.parentNode.parentNode); obj.parentNode.parentNode.parentNode.parentNode.style.display = 'none'; } } /* //确定或取消图片 以及 超链接输入 function submitPictureInput(){ var inputValue = $("div.pictureInputDIVCls input").val(); if(inputValue == ""){ alert("请输入图片url地址!"); return; } var result = document.execCommand('insertImage', false, inputValue); if(!result){ alert("图片插入失败"); } $("div.pictureInputDIVCls").css("display","none"); } function cancelPictureInput(){ $("div.pictureInputDIVCls").css("display","none"); } function submitLinkInput(){ var inputValue = $("div.linkInputDIVCls input").val(); if(inputValue == ""){ alert("请输入超链接url地址!"); return; } var result = document.execCommand('createLink', false, inputValue); if(!result){ alert("超链接插入失败"); } $("div.linkInputDIVCls").css("display","none"); } function cancelLinkInput(){ $("div.linkInputDIVCls").css("display","none"); } */

textEditor.css

.customed-textEditor-cls .editor-content-cls{
    resize:vertical; 
    overflow:auto; 
    border:1px solid silver; 
    border-radius:5px; 
    min-height:200px;
    box-shadow: inset 0 0 10px silver;
    padding:1em;
}

/*图片的最大大小*/
div.customed-textEditor-cls img{
    max-width:70%;
    max-height:70%;
    margin-left:15%;
}
.customed-textEditor-cls .content {
    margin: 100px;
}

/*字体选择框*/
.fontSizeDlgCls ul{
    border:1px solid #ddd;
    width:40px;
    margin-left:0px;
    background-color:#fff;
}
.fontSizeDlgCls li{
    list-style:none;
}
.fontSizeDlgCls li a{
    color:#000;
    width:40px;
    display:inline-block;
}
.fontSizeDlgCls li:hover{
    background-color:#0b569e;
}
.fontSizeDlgCls li:hover a{
    color:#fff;
}

/* 20170328 颜色表*/
table.colorTableCls {
    border:2px solid #eee;
}

table.colorTableCls td{
    width:12px;
    height:12px;
    cursor:pointer;
    padding:0px;
    margin:0px;
}

/*颜色表*/
div.colorTableDIVCls {
    background-color:#fff;
}

/*图片地址输入框和超链接输入框*/
div.tipCls{
    font-size:15px;
    font-weight:600;
    margin-top:15px;
    margin-bottom:10px;
}
input.inputTextCls{
    margin-left:20px;
    width:300px;
    height:28px;
    border-radius:5px;
    margin-bottom:15px;
}
div.pictureInputDIVCls{
    border:2px solid #eee;
    width:400px;
    height:120px;
    padding-bottom:20px;
    background-color:#fff;
}
div.linkInputDIVCls{
    border:2px solid #eee;
    width:400px;
    height:120px;
    padding-bottom:20px;
    background-color:#fff;
}

textEditor.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>文本编辑器插件</title>
        <!-- bootstrap.min.css -->
        <!-- 通过<div class="Container-fluid">创建流式布局  适合应用于程序和文档类的网站-->
        <link rel="stylesheet" th:href="@{/bootstrap/bootstrap-combined.min.css}" />
        <!-- font-awesome 提供了大量的字体图标 可供使用 -->
        <link rel="stylesheet" th:href="@{/css/font-awesome/font-awesome.css}" />
        <link rel="stylesheet" th:href="@{/css/customedPlugins/textEditor.css}" />

        <style type="text/css"> 

        </style>
    </head> 
    <body>

        <h2>
                     文本编辑框测试
        </h2>

        <div id="textEditorDIV" class="customed-textEditor-cls">
        </div> 

        <!--[if !IE]><!-->
        <script th:src="@{/jquery/2.1.4/jquery-2.1.4.min.js}"></script>
        <!--<![endif]--> 

        <!--[if IE]><!-->
        <script th:src="@{/jquery/1.11.0/jquery-1.11.0.min.js}"></script>
        <!--<![endif]-->

        <script th:src="@{/bootstrap/3.3.5/js/bootstrap.min.js}"></script>

        <script th:src="@{/js/customedPlugins/textEditor.js}"></script>

        <script th:inline="javascript">
         /*<![CDATA[*/      
                 $("#textEditorDIV").textEditor();


        /*]]>*/
        </script>       
    </body>
</html>

效果展示:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值