【问题标题】:How to format/tidy/beautify in JavaScript如何在 JavaScript 中格式化/整理/美化
【发布时间】:2010-10-12 09:48:53
【问题描述】:

如何在 JavaScript 中格式化/整理/美化 HTML? I have tried doing a search/replace for angle brackets (<, >) and indenting accordingly. 当然不考虑HTML里面是JS还是CSS等。

我想这样做的原因是我制作了一个内容编辑器 (CMS),它同时具有所见即所得和源代码视图。所见即所得编辑器编写的代码的问题通常是一行。所以我想要一个可以按需将其格式化为更易读的形式的 JavaScript。

这是我目前所拥有的:

function getIndent(level) {
    var result = '',
        i = level * 4;
    if (level < 0) {
        throw "Level is below 0";
    }
    while (i--) {
        result += ' ';
    }
    return result;
}

function style_html(html) {
    html = html.trim();
    var result = '',
        indentLevel = 0,
        tokens = html.split(/</);
    for (var i = 0, l = tokens.length; i < l; i++) {
        var parts = tokens[i].split(/>/);
        if (parts.length === 2) {
            if (tokens[i][0] === '/') {
                indentLevel--;
            }
            result += getIndent(indentLevel);
            if (tokens[i][0] !== '/') {
                indentLevel++;
            }

            if (i > 0) {
                result += '<';
            }

            result += parts[0].trim() + ">\n";
            if (parts[1].trim() !== '') {
                result += getIndent(indentLevel) + parts[1].trim().replace(/\s+/g, ' ') + "\n";
            }

            if (parts[0].match(/^(img|hr|br)/)) {
                indentLevel--;
            }
        } else {
            result += getIndent(indentLevel) + parts[0] + "\n";
        }
    }
    return result;
}

【问题讨论】:

  • 有时最好的问题/答案是题外话。
  • @NilsB 垃圾这是话题,实际上它已经作为题外话关闭了,然后又重新打开了
  • 您的代码运行良好,但仍需要一些改进。支持更多的单例或空标签。尝试更改匹配方法 if (parts[0].match(/^(area|base|br|col|command|embed|hr|img|input|link|meta|param|source)/))。还更新: return result.trim();而不是 html = html.trim();

标签: javascript jquery html


【解决方案1】:

我使用这种方法来格式化 HTML。很简单,但确实有效:

function format(html) {
    var tab = '\t';
    var result = '';
    var indent= '';

    html.split(/>\s*</).forEach(function(element) {
        if (element.match( /^\/\w/ )) {
            indent = indent.substring(tab.length);
        }

        result += indent + '<' + element + '>\r\n';

        if (element.match( /^<?\w[^>]*[^\/]$/ ) && !element.startsWith("input")  ) { 
            indent += tab;              
        }
    });

    return result.substring(1, result.length-3);
}

【讨论】:

  • 很好的解决方案。虽然它没有缩进,也没有格式化 CSS,但它是一个非常快速和肮脏的,而且非常简短。
  • @johnywhy 似乎可以很好地处理缩进。
  • 我建议将 \t 更改为 4 个空格
  • 这对 HTML 非常有用,非常感谢! CSS有没有类似的快速解决方案?
  • 它非常简单但很好。但是当标签如be、hr时计算错误
【解决方案2】:

@lovasoa How to format/tidy/beautify in JavaScript 是一个很好的解决方案。
坚如磐石,比 vkBeautify 甚至 CodeMirror(难以使用 AMD)好得多,而且非常简单

<script src='http://lovasoa.github.io/tidy-html5/tidy.js'></script>
<script>
  options = {
  "indent":"auto",
  "indent-spaces":2,
  "wrap":80,
  "markup":true,
  "output-xml":false,
  "numeric-entities":true,
  "quote-marks":true,
  "quote-nbsp":false,
  "show-body-only":true,
  "quote-ampersand":false,
  "break-before-br":true,
  "uppercase-tags":false,
  "uppercase-attributes":false,
  "drop-font-tags":true,
  "tidy-mark":false
}

var html = document.querySelector("body").outerHTML;
var result = tidy_html5(html, options);
console.log(result);
</script>

【讨论】:

【解决方案3】:

我需要类似的东西,这是我的解决方案,灵感来自 michal.jakubeczy 提供的方法。为了在&lt;pre&gt; 标签中保留格式,这有点复杂。希望这会对某人有所帮助。

function formatHTML(html) {
    var indent = '\n';
    var tab = '\t';
    var i = 0;
    var pre = [];

    html = html
        .replace(new RegExp('<pre>((.|\\t|\\n|\\r)+)?</pre>'), function (x) {
            pre.push({ indent: '', tag: x });
            return '<--TEMPPRE' + i++ + '/-->'
        })
        .replace(new RegExp('<[^<>]+>[^<]?', 'g'), function (x) {
            var ret;
            var tag = /<\/?([^\s/>]+)/.exec(x)[1];
            var p = new RegExp('<--TEMPPRE(\\d+)/-->').exec(x);

            if (p) 
                pre[p[1]].indent = indent;

            if (['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr'].indexOf(tag) >= 0) // self closing tag
                ret = indent + x;
            else {
                if (x.indexOf('</') < 0) { //open tag
                    if (x.charAt(x.length - 1) !== '>')
                        ret = indent + x.substr(0, x.length - 1) + indent + tab + x.substr(x.length - 1, x.length);
                    else 
                        ret = indent + x;
                    !p && (indent += tab);
                }
                else {//close tag
                    indent = indent.substr(0, indent.length - 1);
                    if (x.charAt(x.length - 1) !== '>')
                        ret =  indent + x.substr(0, x.length - 1) + indent + x.substr(x.length - 1, x.length);
                    else
                        ret = indent + x;
                }
            }
            return ret;
        });

    for (i = pre.length; i--;) {
        html = html.replace('<--TEMPPRE' + i + '/-->', pre[i].tag.replace('<pre>', '<pre>\n').replace('</pre>', pre[i].indent + '</pre>'));
    }

    return html.charAt(0) === '\n' ? html.substr(1, html.length - 1) : html;
}

function unformatHTML(html) {
    var i = 0;
    var pre = [];

    html = html.replace(new RegExp('<pre>((.|\\t|\\n|\\r)+)?</pre>'), function (x) {
        pre.push(x);
        return '<--TEMPPRE' + i++ + '/-->'
    }).replace(/\n/g, '').replace(/\t/g, '');

    for (i = pre.length; i--;) {
        html = html.replace('<--TEMPPRE' + i + '/-->', pre[i]);
    }

    html = html.replace(new RegExp('<pre>\\n'), '<pre>').replace(new RegExp('\\n\\t*</pre>'), '</pre>');
    return html;
}

【讨论】:

  • 它可以工作,但会添加一些空行并将所有内容换成新行
  • 这个比较好;但是我必须在格式化之前取消格式化 HTML 以逃避乘法换行错误。
  • @pendingfox unformatHTML 已添加到此解决方案中。
【解决方案4】:

我发现 js-beautify 远远优于迄今为止发布的任何解决方案。

script 添加到您的 lib 文件夹:

像往常一样带入标题:

<script src="libs/beautify.js"></script>

在页面上的任何位置定位代码(例如precode 标记)并使用js_beautify 函数根据需要进行格式化:

$(".my_class").text(js_beautify($(".my_class").text()))

这将根据需要进行格式化。 repo 上提供了各种配置选项。

【讨论】:

    【解决方案5】:

    如果你安装了 node.js,你也可以使用命令行工具

    运行npm install -g uglify-js 全局安装uglifyjs,查看here 获取文档。

    那你可以uglify index.min.js -b -o index.js

    【讨论】:

    • 我的问题是因为您的解决方案是用于开发的,并且我认为在浏览器中没有运行时是有意的。
    【解决方案6】:

    jQuery 创建者 John Resig 编写了一个快速轻量级的 HTML parser in javascript。如果您正在寻找可以直接添加到 CMS 的解决方案,那么您可以使用此解析器作为基础编写一个简单的美化器。您需要做的就是使用内置 api 重新输出添加空格和换行符的元素:

    HTMLParser(htmlString, {
      start: function(tag, attrs, unary) {},
      end: function(tag) {},
      chars: function(text) {},
      comment: function(text) {}
    });
    

    这种方法的另一个好处是您可以使用相同的 HTMLParser 将 HTML 读回您的 WYSIWYG,或者以其他方式与用户的 HTML 树进行交互。 HTMLParser 还预先构建了一个 HTMLtoDOM 方法。

    【讨论】:

      【解决方案7】:

      我相信chrome和firebug的调试代码显示引擎都是用JS写的。不过,这可能比你真正想要的要重。

      【讨论】:

        【解决方案8】:

        写在一行上会更快地下载到浏览器,所以我不确定是否要对其进行格式化。也许是格式化版本或优化版本的选项。

        至于问题...您可以在执行这么多操作后调用 并将代码发送到服务器进行格式化并显示在屏幕上的不同框中。基本上它会是这个网站的实时版本,http://infohound.net/tidy/

        【讨论】:

        • 是的,它会稍微快一点(比如 0.0001 秒)。但是考虑到所见即所得的编辑器是针对对 HTML 知之甚少的客户,格式化的 HTML 使它更容易。同样关于将数据发送到服务器进行格式化,这也很不理想。
        【解决方案9】:

        Resig 的格式化程序因一个非常简单的测试用例而失败:

        http://ejohn.org/apps/htmlparser/

        在输入框中输入:

        <script src="/files/htmlparser.js"></script>
        <script>
        var x = 1;
        </script>
        

        输出框渲染:

        <script src="/files/htmlparser.js"></script>
        <script></script>
        var x = 1;
        

        【讨论】:

        • 你没有回答这个问题
        猜你喜欢
        • 2014-10-15
        • 1970-01-01
        • 1970-01-01
        • 2011-02-14
        • 1970-01-01
        • 2011-07-17
        • 1970-01-01
        • 2016-09-29
        • 2018-09-28
        相关资源
        最近更新 更多