如何在浏览器中实现文本编辑器

时间:2012-09-26 14:34:20

标签: browser text-editor

这纯粹是一种自我改进和教育的练习。我正在尝试在浏览器中实现类似vi的文本编辑器的扩展。有谁知道我会怎么做呢?

1 个答案:

答案 0 :(得分:1)

我几周前为一个项目创建了一个非常基本的编辑器。它可以让你开始:)把这个代码扔进一个JS文件,在你的网页上添加对它的引用

将此添加到您的

$("#msgBody").SiteRtfEditor();

将此添加到您的身体html:

<textarea id="msgBody"></textarea>

JS代码:

(function ($) {
$.fn.SiteRtfEditor = function (options) {

    var defaults = {
        iFrameUrl: "",
        width: "100%",
        height: "100%",
        showModes: true
    };
    var opts = $.extend(defaults, options);

    return this.each(function () {
        var thisControlID = this.id.toString();
        var rtfEditorID = "SiteRtfEditor_" + thisControlID.toString();
        var swatchCommand = "forecolor";

        $("<style type='text/css'>." + rtfEditorID + "_Swatch{display:block;width:13px;height:13px;margin:0;padding:0px;border:1px solid #d3d3d3;border-spacing:0px;border-collapse:collapse;}</style>").appendTo("head");

        //Build HTML
        var htmlOutput = "<div id='rtfEditorControls' style='padding:0px;margin:3px;text-align:left;line-height:21px;vertical-align:middle;white-space:nowrap;'>";            
        htmlOutput += "<select id='" + rtfEditorID + "_FontFamily'>";
        htmlOutput += "<option value='Arial'>Arial</option>";
        htmlOutput += "<option value='Comic Sans MS'>Comic Sans MS</option>";
        htmlOutput += "<option value='Courier New'>Courier New</option>";
        htmlOutput += "<option value='Monotype Corsiva'>Monotype</option>";
        htmlOutput += "<option value='Tahoma'>Tahoma</option>";
        htmlOutput += "<option value='Times'>Times</option>";
        htmlOutput += "</select>&nbsp;&nbsp;<select id='" + rtfEditorID + "_FontSize'>";
        htmlOutput += "<option value='8'>8pt</option><option value='10'>10pt</option><option value='12'>12pt</option><option value='14'>14pt</option>";
        htmlOutput += "<option value='16'>16pt</option><option value='18'>18pt</option><option value='20'>20pt</option><option value='22'>22pt</option>";
        htmlOutput += "<option value='24'>24pt</option><option value='28'>28pt</option><option value='32'>32pt</option><option value='36'>36pt</option>";
        htmlOutput += "</select><br />";
        htmlOutput += "<input type='button' id='" + rtfEditorID + "_Bold' style='height:21px;width:21px;font-weight:bold;margin:2px;padding:0px;border:1px solid #000000;' value='B' />";
        htmlOutput += "<input type='button' id='" + rtfEditorID + "_Italic' style='height:21px;width:21px;font-style:italic;margin:2px;padding:0px;border:1px solid #000000;' value='I' />";
        htmlOutput += "<input type='button' id='" + rtfEditorID + "_Underline' style='height:21px;width:21px;text-decoration:underline;margin:2px;padding:0px;border:1px solid #000000;' value='U' />";
        htmlOutput += "<input type='button' id='" + rtfEditorID + "_BackColor' style='border:0px;height:16px;width:16px;margin:2px 6px 2px 6px;padding:0px;background:#ffffff url(/Images/BackColor.gif) no-repeat;' />";
        htmlOutput += "<input type='button' id='" + rtfEditorID + "_ForeColor' style='border:0px;height:16px;width:16px;margin:2px 6px 2px 6px;padding:0px;background:#ffffff url(/Images/ForeColor.gif) no-repeat;' />";
        htmlOutput += "<div id='" + rtfEditorID + "_ColorPalette' style='position:absolute;z-index:202;display:none;margin:0px;background-color:#ffffff;border:1px solid #a7abb0;'></div>";
        htmlOutput += "</div>";
        htmlOutput += "<div style='position:relative;z-index:200;width:100%;height:100%;margin:0px;padding:0px;'><iframe id='" + rtfEditorID + "_Frame' frameborder='0' marginheight='0' marginwidth='0' scrolling='auto' windowless='true' style='width:99%;height:100%;border-spacing:0px;border-collapse:collapse;border:1px solid #d3d3d3;background-color:#ffffff;padding:0px;margin-left:auto;margin-right:auto;position:relative;z-index:201;'></iframe></div>";

        if (opts.showModes) {
            htmlOutput += "<div style='width:100%;text-align:left;'><input type='button' id='" + rtfEditorID + "_DesignerMode' style='border:0;background:transparent;font-weight:bold;' value='Design' />&nbsp;&nbsp;<input type='button' id='" + rtfEditorID + "_SourceMode' style='border:0;background:transparent;' value='Source' /></div>";
        }

        $("#" + thisControlID).before("<div id='" + rtfEditorID + "' style='position:relative;padding:0px;margin:0px;border:1px solid #d3d3d3;background-color:#f1f1f1;width:" + opts.Width + ";height:" + opts.Height + ";text-align:center;'>");
        $("#" + thisControlID).css("width", "98%").css("height", "100%").css("margin", "auto");
        $("#" + thisControlID).hide();
        $("#" + rtfEditorID).html(htmlOutput);
        $("#" + rtfEditorID + "_Frame").after($("#" + thisControlID));
        BuildColorPalette(rtfEditorID + "_ColorPalette");

        function BuildColorPalette(paletteID) {
            var paletteHtml = "";
            var firstRowList = ["ffffff", "000000", "eeece1", "1f497d", "4f81bd", "c0504d", "9bbb59", "8064a2", "4bacc6", "f79646"];
            var colorcol1 = ["f2f2f2", "d8d8d8", "bfbfbf", "a5a5a5", "7f7f7f"];
            var colorcol2 = ["7f7f7f", "595959", "3f3f3f", "262626", "0c0c0c"];
            var colorcol3 = ["ddd9c3", "c4bd97", "938953", "494429", "1d1b10"];
            var colorcol4 = ["c6d9f0", "8db3e2", "548dd4", "17365d", "0f243e"];
            var colorcol5 = ["dbe5f1", "b8cce4", "95b3d7", "366092", "244061"];
            var colorcol6 = ["f2dcdb", "e5b9b7", "d99694", "953734", "632423"];
            var colorcol7 = ["ebf1dd", "d7e3bc", "c3d69b", "76923c", "4f6128"];
            var colorcol8 = ["e5e0ec", "ccc1d9", "b2a2c7", "5f497a", "3f3151"];
            var colorcol9 = ["dbeef3", "b7dde8", "92cddc", "31859b", "205867"];
            var colorcol10 = ["fdeada", "fbd5b5", "fac08f", "e36c09", "974806"];
            var lastRowList = ["c00000", "ff0000", "ffc000", "ffff00", "92d050", "00b050", "00b0f0", "0070c0", "002060", "7030a0"];

            //First first
            paletteHtml = "<table style='margin:3px;'><tr><td colspan='10'>Theme Colors</td></tr><tr>";
            for (i = 0; i < firstRowList.length; i++) {
                paletteHtml += "<td><input type='button' class='" + rtfEditorID + "_Swatch' title='#" + firstRowList[i] + "' style='background-color:#" + firstRowList[i] + ";' /></td>";
            };
            paletteHtml += "</tr><tr><td colspan='10' style='height:5px;'></td></tr><tr>";

            //Middle shades
            paletteHtml += "<td>" + BuildShadeColumn(colorcol1) + "</td>";
            paletteHtml += "<td>" + BuildShadeColumn(colorcol2) + "</td>";
            paletteHtml += "<td>" + BuildShadeColumn(colorcol3) + "</td>";
            paletteHtml += "<td>" + BuildShadeColumn(colorcol4) + "</td>";
            paletteHtml += "<td>" + BuildShadeColumn(colorcol5) + "</td>";
            paletteHtml += "<td>" + BuildShadeColumn(colorcol6) + "</td>";
            paletteHtml += "<td>" + BuildShadeColumn(colorcol7) + "</td>";
            paletteHtml += "<td>" + BuildShadeColumn(colorcol8) + "</td>";
            paletteHtml += "<td>" + BuildShadeColumn(colorcol9) + "</td>";
            paletteHtml += "<td>" + BuildShadeColumn(colorcol10) + "</td>";

            //Last row
            paletteHtml += "</tr><tr><td colspan='10'>Standard Colors</td></tr><tr>";
            for (i = 0; i < lastRowList.length; i++) {
                paletteHtml += "<td><input type='button' class='" + rtfEditorID + "_Swatch' title='#" + lastRowList[i] + "' style='background-color:#" + lastRowList[i] + ";' /></td>";
            };

            paletteHtml += "</tr></table>";
            $("#" + paletteID).html(paletteHtml);
        }; //BuildColorPalette

        function BuildShadeColumn(colorList) {
            var tempHtml = "<table style='margin:0px;padding:0px;width:13px;'><tr><td>";
            for (i = 0; i < colorList.length; i++) {
                tempHtml += "<input type='button' class='" + rtfEditorID + "_Swatch' title='#" + colorList[i] + "' style='background-color:#" + colorList[i] + ";' />";
            }
            tempHtml += "</td></tr></table>";
            return tempHtml;
        }; //BuildShadeColumn

        $(function () {
            if (opts.iFrameUrl.length != 0) { $("#" + rtfEditorID + "_Frame").attr("src", opts.iFrameUrl.toString()); };

            document.getElementById(rtfEditorID + "_Frame").contentWindow.document.designMode = "on";
            document.getElementById(rtfEditorID + "_Frame").contentWindow.document.close();

            $("#" + rtfEditorID + "_DesignerMode").click(function() {
                $("#" + rtfEditorID + "_SourceMode").css("font-weight", "normal");
                $("#" + rtfEditorID + "_DesignerMode").css("font-weight", "bold");
                $("#" + thisControlID).hide();
                $("#" + rtfEditorID + "_Frame").show();

            });

            $("#" + rtfEditorID + "_SourceMode").click(function() {
                $("#" + rtfEditorID + "_SourceMode").css("font-weight", "bold");
                $("#" + rtfEditorID + "_DesignerMode").css("font-weight", "normal");
                $("#" + thisControlID).show();
                $("#" + rtfEditorID + "_Frame").hide();
            });

            $("#" + rtfEditorID + "_BackColor").click(function () {
                swatchCommand = "backcolor";
                $("#" + rtfEditorID + "_ColorPalette").toggle();
            });

            $("#" + rtfEditorID + "_ForeColor").click(function () {
                swatchCommand = "forecolor";
                $("#" + rtfEditorID + "_ColorPalette").toggle();
            });

            //http://msdn.microsoft.com/en-us/library/ms533049(VS.85).aspx for execCommand options
            $("." + rtfEditorID + "_Swatch").click(function () {
                var edit = document.getElementById(rtfEditorID + "_Frame").contentWindow;
                edit.focus();
                edit.document.execCommand(swatchCommand, false, $(this).attr("title").toString());
                edit.focus();
                $("#" + rtfEditorID + "_ColorPalette").toggle();
            });

            $("#" + rtfEditorID + "_Bold").click(function () {
                var edit = document.getElementById(rtfEditorID + "_Frame").contentWindow;
                edit.focus();
                edit.document.execCommand("bold", false, "");
                edit.focus();
            });

            $("#" + rtfEditorID + "_Italic").click(function () {
                var edit = document.getElementById(rtfEditorID + "_Frame").contentWindow;
                edit.focus();
                edit.document.execCommand("italic", false, "");
                edit.focus();
            });

            $("#" + rtfEditorID + "_Underline").click(function () {
                var edit = document.getElementById(rtfEditorID + "_Frame").contentWindow;
                edit.focus();
                edit.document.execCommand("underline", false, "");
                edit.focus();
            });

            $("#" + rtfEditorID + "_FontFamily").change(function () {
                var edit = document.getElementById(rtfEditorID + "_Frame").contentWindow;
                edit.focus();
                edit.document.execCommand("fontname", false, $("#" + rtfEditorID + "_FontFamily").val());
                edit.focus();
            });

            $("#" + rtfEditorID + "_FontSize").change(function () {
                var edit = document.getElementById(rtfEditorID + "_Frame").contentWindow;
                edit.focus();
                edit.document.execCommand("fontsize", false, $("#" + rtfEditorID + "_FontSize").val());
                edit.focus();
            });

            $("#" + rtfEditorID + "_Frame").blur(function () {
                $("#" + thisControlID).val(frames[rtfEditorID + "_Frame"].document.body.innerHTML.toString());
            }); //update textbox control when editor loses focus

            //Give iFrame default content
            var newIFrame = frames[rtfEditorID + "_Frame"].document;
            newIFrame.open();
            newIFrame.close();
        });

        $.fn.SiteRtfEditorVal = function (htmlValue) {
            if (htmlValue == null | htmlValue == "undefined") {
                //Get
                try {
                    return frames[rtfEditorID + "_Frame"].document.body.innerHTML.toString();
                } catch (err) {
                    return "";
                }
            } else {
                //Set
                $("#" + rtfEditorID + "_Frame").load(function () {
                    $("#" + thisControlID).val(htmlValue);
                    frames[rtfEditorID + "_Frame"].document.body.innerHTML = htmlValue;
                });
                //If already loaded, it seems to skip the callback function, so we 'try' to set it one more time.
                try {
                    $("#" + thisControlID).val(htmlValue);
                    frames[rtfEditorID + "_Frame"].document.body.innerHTML = htmlValue;
                } catch(err) {
                }
            }
        } //rtfEditorHtml

    }); //return this.each
} //$.fn.SiteRtfEditor

})(jQuery);