JS,HTML。 Google美化。如何将美化的 html 代码动态地插入 html 页面中的 contenteditable div

JS, HTML. Google prettify. How to insert prettified html code into contenteditable div in html page dynamically

我正在写一个 Messenger,我的目标是添加一个机会来插入代码并突出显示它,就像在 Stack Overflow 上所做的那样。我正在使用 Google 的美化库。 这是 html 部分:

<div id="test" style="margin-left: auto; margin-right: auto; overflow-y: scroll;" contenteditable="true"
                 placeholder="Type your message" name="message" ng-model="message">
            </div>

和js函数:

$scope.pasteHtmlAtCaret = function () {
            document.getElementById('test').focus();
            var sel, range;
            if (window.getSelection) {
                // IE9 and non-IE
                sel = window.getSelection();
                if (sel.getRangeAt && sel.rangeCount) {
                    range = sel.getRangeAt(0);

                    // Range.createContextualFragment() would be useful here but is
                    // only relatively recently standardized and is not supported in
                    // some browsers (IE9, for one)
                    var el = document.createElement("div");
                    //var el = document.getElementById('test');

                    /*var text = sel.toString().replace(/</g, "&lt;");
                    text = text.replace(/>/g, "&gt;");
                    text = text.replace(/&/g, "&amp;");*/

                    el.innerHTML = "<pre class=prettyprint linenums><code>" + sel.toString() + '</code></pre></br>';

                    range.deleteContents();

                    var frag = document.createDocumentFragment(), node, lastNode;
                    while ((node = el.firstChild)) {
                        lastNode = frag.appendChild(node);
                    }
                    var firstNode = frag.firstChild;
                    range.insertNode(frag);
                    prettyPrint();
                    // Preserve the selection
                    if (lastNode) {
                        range = range.cloneRange();
                        range.setStartAfter(lastNode);
                        range.setStartBefore(firstNode);

                        sel.removeAllRanges();
                        sel.addRange(range);
                    }
                }
            } else if ((sel = document.selection) && sel.type != "Control") {
                var originalRange = sel.createRange();
                originalRange.collapse(true);
                sel.createRange().pasteHTML(html);

                range = sel.createRange();
                range.setEndPoint("StartToStart", originalRange);
                range.select();
            }
        }

如您所见,我已经尝试放置&lt;(在注释中)和其他符号来代替<、>、& 符号。但是,它们在 js 代码中显示,而不是符号。请告诉我如何在我的 div 块(或者可能是另一个容器)中插入美化的 html 代码。

也许,你也可以告诉我,如何美化显示行号,因为它们现在没有显示(它们被当作另一个 class 不知何故)

Afaict,您正在创建一个 <pre class=prettyprint>,但美化库实际上从未被调用过。

我认为您可以只使用 PR.prettyPrintOne 并传入您的 HTML 源代码。您应该首先转义 &<> 是正确的,因为它需要 HTML,而不是纯源代码。

PR.prettyPrintOne 在加载 <script src=".../prettify.js"></script> 时可用,但在加载 <script src=".../run_prettify.js"></script>.

时不可用
/*var text = sel.toString().replace(/</g, "&lt;");
text = text.replace(/>/g, "&gt;");
text = text.replace(/&/g, "&amp;");*/

这里有一个错误。你应该先做 .replace(/&/g, "&amp;") 因为

"<".replace(/</g, "&lt;").replace(/&/g, "&amp;") === "&amp;lt;"

"<".replace(/&/g, "&amp;").replace(/</g, "&lt;") === "&lt;"

当一些替换字符串也匹配模式时,替换顺序很重要:)

function htmlEscape(s) {
  return (String(s).replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;"));
}