【问题标题】:Textarea toolbar?文本区域工具栏?
【发布时间】:2011-07-27 23:49:19
【问题描述】:

我一直在为 textarea 设计一个格式化工具栏,很像在这个网站上写问题的工具栏(带有粗体、斜体、下划线按钮)。唯一的区别是我需要按钮来使文本变为粗体,而不仅仅是添加粗体标签。我需要的是类似于 Instructables.com 富评论编辑器、newgrounds.com 评论编辑器或谷歌文档。有没有人知道如何使 textarea 中的某些文本显示为粗体、斜体或下划线,但保留其余部分?

【问题讨论】:

  • 只看谷歌文档的 html:他们使用
    。即具有相同格式的每个连续文本块都在

标签: javascript html


【解决方案1】:

有很多 javascript WYSIWYG 编辑器的实现。 FCKEditor(现为CKEditor)是首批之一。 TinyMCE 流行了很长时间。我最近使用了TinyEditor

还有nicedit,10 位编辑列出并比较了here,更不用说之前在SO 上针对what's available 的问题提供的答案了。

他们不必制作 HTML - 也有编辑制作 Wiki markup

为什么要重新发明轮子?

【讨论】:

    【解决方案2】:

    我发现了如何像这样创建自己的富文本编辑器:

    (function ($) {
        if (typeof $.fn.rte === "undefined") {
            var defaults = {
                content_css_url: "rte.css",
                media_url: "images",
                dot_net_button_class: null,
                max_height: 350
            };
            $.fn.rte = function (options) {
                $.fn.rte.html = function (iframe) {
                    return iframe.contentWindow.document.getElementsByTagName("body")[0].innerHTML;
                };
                var opts = $.extend(defaults, options);
                return this.each(function () {
                    var textarea = $(this);
                    var iframe;
                    var myID = textarea.attr("id");
                    var settings = $.meta ? $.extend({}, opts, textarea.data()) : opts;
                    var sel = {
                        cmdBtnSelector: "." + settings.dot_net_button_class
                    };
    
    
                    function enableDesignMode() {
                        var content = textarea.val();
                        if ($.trim(content) == '') {
                            content = '<br />';
                        }
                        if (iframe) {
                            textarea.hide();
                            $(iframe).contents().find("body").html(content);
                            $(iframe).show();
                            $("#toolbar-" + myID).remove();
                            textarea.before(toolbar());
                            return true;
                        }
                        iframe = document.createElement("iframe");
                        iframe.frameBorder = 0;
                        iframe.frameMargin = 0;
                        iframe.framePadding = 0;
                        iframe.height = 200;
                        if (textarea.attr('class')) iframe.className = textarea.attr('class');
                        if (textarea.attr('id')) iframe.id = myID;
                        if (textarea.attr('name')) iframe.title = textarea.attr('name');
                        textarea.after(iframe);
                        var css = "";
                        if (settings.content_css_url) {
                            css = "<link type='text/css' rel='stylesheet' href='" + settings.content_css_url + "' />";
                        }
                        var doc = "<html><head>" + css + "</head><body class='frameBody'>" + content + "</body></html>";
                        tryEnableDesignMode(doc, function () {
                            $("#toolbar-" + myID).remove();
                            textarea.before(toolbar());
                            textarea.hide();
                        });
                    }
                    function tryEnableDesignMode(doc, callback) {
                        if (!iframe) {
                            return false;
                        }
                        try {
                            iframe.contentWindow.document.open();
                            iframe.contentWindow.document.write(doc);
                            iframe.contentWindow.document.close();
                        } catch (error) {
                            console.log(error)
                        }
                        if (document.contentEditable) {
                            iframe.contentWindow.document.designMode = "On";
                            callback();
                            return true;
                        } else if (document.designMode != null) {
                            try {
                                iframe.contentWindow.document.designMode = "on";
                                callback();
                                return true;
                            } catch (error) {
                                console.log(error)
                            }
                        }
                        setTimeout(function () {
                            tryEnableDesignMode(doc, callback)
                        }, 250);
                        return false;
                    }
                    function disableDesignMode(submit) {
                        var content = $(iframe).contents().find("body").html();
                        if ($(iframe).is(":visible")) {
                            textarea.val(content);
                        }
                        if (submit !== true) {
                            textarea.show();
                            $(iframe).hide();
                        }
                    }
                    function toolbar() {
                        var tb = $("<div class='rte-toolbar' id='toolbar-" + myID + "'><div>\
                  <p>\
                      <select>\
                          <option value=''>Block style</option>\
                          <option value='p'>Paragraph</option>\
                          <option value='h3'>Title</option>\
                      </select>\
                  </p>\
                  <p>\
                      <a href='#' class='bold'><img src='" + settings.media_url + "text_bold.png' alt='bold' title='Bold' /></a>\
                      <a href='#' class='italic'><img src='" + settings.media_url + "text_italic.png' alt='italic' title='Italicize' /></a>\
                  </p>\
                  <p>\
                      <a href='#' class='unorderedlist'><img src='" + settings.media_url + "text_list_bullets.png' alt='unordered list' title='Unordered List' /></a>\
                      <a href='#' class='link'><img src='" + settings.media_url + "link.png' alt='link' title='Hyperlink' /></a>\
                      <a href='#' class='image'><img src='" + settings.media_url + "image.png' alt='image' title='Image' /></a>\
                      <a href='#' class='disable'><img src='" + settings.media_url + "code.png' alt='close rte' title='View Code' /></a>\
                  </p></div></div>");
                        $('select', tb).change(function () {
                            var index = this.selectedIndex;
                            if (index != 0) {
                                var selected = this.options[index].value;
                                formatText("formatblock", '<' + selected + '>');
                            }
                        });
                        $('.bold', tb).click(function () {
                            formatText('bold');
                            return false;
                        });
                        $('.italic', tb).click(function () {
                            formatText('italic');
                            return false;
                        });
                        $('.unorderedlist', tb).click(function () {
                            formatText('insertunorderedlist');
                            return false;
                        });
                        $('.link', tb).click(function () {
                            var p = prompt("URL:");
                            if (p) formatText('CreateLink', p);
                            return false;
                        });
                        $('.image', tb).click(function () {
                            var p = prompt("image URL:");
                            if (p) formatText('InsertImage', p);
                            return false;
                        });
                        $('.disable', tb).click(function () {
                            disableDesignMode();
                            var edm = $('<a href="#">Enable design mode</a>');
                            tb.empty().append(edm);
                            edm.click(function (e) {
                                e.preventDefault();
                                enableDesignMode();
                                $(this).remove();
                            });
                            return false;
                        });
                        if (settings.dot_net_button_class != null) {
                            var cmdBtn = $(iframe).parents('form').find(sel.cmdBtnSelector);
                            cmdBtn.click(function () {
                                disableDesignMode(true);
                            });
                        } else {
                            $(iframe).parents('form').submit(function () {
                                disableDesignMode(true);
                            });
                        }
                        var iframeDoc = $(iframe.contentWindow.document);
                        var select = $('select', tb)[0];
                        iframeDoc.mouseup(function () {
                            setSelectedType(getSelectionElement(), select);
                            return true;
                        });
                        iframeDoc.keyup(function () {
                            setSelectedType(getSelectionElement(), select);
                            var body = $('body', iframeDoc);
                            if (body.scrollTop() > 0) {
                                var iframe_height = parseInt(iframe.style['height']);
                                if (isNaN(iframe_height)) {
                                    iframe_height = 0;
                                }
                                var h = Math.min(opts.max_height, iframe_height + body.scrollTop()) + 'px';
                                iframe.style['height'] = h;
                            }
                            return true;
                        });
                        return tb;
                    }
                    function formatText(command, option) {
                        iframe.contentWindow.focus();
                        try {
                            iframe.contentWindow.document.execCommand(command, false, option);
                        } catch (e) {
                            console.log(e)
                        }
                        iframe.contentWindow.focus();
                    }
                    function setSelectedType(node, select) {
                        while (node.parentNode) {
                            var nName = node.nodeName.toLowerCase();
                            for (var i = 0; i < select.options.length; i++) {
                                if (nName == select.options[i].value) {
                                    select.selectedIndex = i;
                                    return true;
                                }
                            }
                            node = node.parentNode;
                        }
                        select.selectedIndex = 0;
                        return true;
                    }
                    function getSelectionElement() {
                        if (iframe.contentWindow.document.selection) {
                            selection = iframe.contentWindow.document.selection;
                            range = selection.createRange();
                            try {
                                node = range.parentElement();
                            } catch (e) {
                                return false;
                            }
                        } else {
                            try {
                                selection = iframe.contentWindow.getSelection();
                                range = selection.getRangeAt(0);
                            } catch (e) {
                                return false;
                            }
                            node = range.commonAncestorContainer;
                        }
                        return node;
                    }
                    enableDesignMode();
                });
            };
        }
    })(jQuery);
    

    【讨论】:

      【解决方案3】:

      contentEditable DOM 属性用于使文档或其一部分可编辑。这不适用于&lt;textarea&gt;;更常见的是创建 &lt;iframe&gt; 并将其中的文档用作编辑器。

      Mark Pilgrim 在 Web 超文本应用技术工作组的博客上有 an article explaining it。它包括an example page,显示了一些正在使用的功能。

      【讨论】:

        猜你喜欢
        • 2018-10-09
        • 1970-01-01
        • 1970-01-01
        • 2013-04-05
        • 2022-06-18
        • 2018-07-03
        • 2018-03-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多