【问题标题】:Sort HTML attributes with JavaScript使用 JavaScript 对 HTML 属性进行排序
【发布时间】:2012-12-06 21:26:24
【问题描述】:

如何使用 JavaScript 对 HTML 属性进行排序?

我有这个 HTML:

<table>
    <tbody>
        <tr>
            <td>Cell 0,0</td>
            <td>Cell 1,0</td>
            <td>Cell 2,0</td>
        </tr>
        <tr>
            <td>Cell 0,1</td>
            <td rowspan="2" colspan="2">Cell 1,1
                <br>Cell 2,1
                <br>Cell 1,2
                <br>Cell 2,2</td>
        </tr>
        <tr>
            <td>Cell 0,2</td>
        </tr>
    </tbody>
</table>

我想将所有元素中的所有属性按字母顺序排序。例如:

<td colspan="2" rowspan="2">Cell 1,1

排序函数可以基于 HTML 字符串、jQuery 对象或节点(不管是哪一个)。

我需要这个的原因是因为我在 2 组 HTML 之间做一个差异(使用 JS,在浏览器中,在单元测试失败后),并且属性顺序使其失败。

所以我的问题是:

如何重新排序节点属性? 或者如何重新排序 HTML 字符串中的属性? 或者如何重新排序 jQuery 元素属性?

我还没有任何代码,因为我不确定哪种方法最好。

【问题讨论】:

  • 更重要的是,你为什么要这样做?
  • 你所描述的毫无意义,几乎是荒谬的。属性根本没有“顺序”。如果您希望它们在您的 HTML 源代码 中排序,那么这与 JavaScript 没有太大关系,除非您的编辑器/IDE 具有内置的 JavaScript 解释器。
  • ^ 同意,到了 NARQ =/
  • @Diodeus — 这是一种编码风格。有利于它的论据。
  • Petah,我想在编写代码以(尝试)重新排列属性之前,我只需要编写一个自定义 HTML-diff(不是 text-diff)来处理这个问题。无论如何,假设您尝试在浏览器中执行此操作,并且差异仅用于显示目的。如果您需要生成一个实际的差异文件,而不是在 Web 浏览器中,JavaScript 似乎是一个奇怪的选择......

标签: javascript html regex


【解决方案1】:

不知道为什么需要用 javascript 来做这件事,但它很感兴趣。好的,根据spec

实现 NamedNodeMap 接口的对象用于表示可以按名称访问的节点集合。注意 NamedNodeMap 不是从 NodeList 继承的; NamedNodeMaps 不以任何特定顺序维护。包含在实现 NamedNodeMap 的对象中的对象也可以通过序号索引访问,但这只是为了方便枚举 NamedNodeMap 的内容,并不意味着 DOM 指定了这些节点的顺序。

所以你可以通过更改数字索引来订购,一段时间后there is我的尝试在 Chrome 中运行顺利。

(function(){
  var xpath = '//table/tbody/tr[2]/td[2]',
      attrs = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null),
      serializer = new XMLSerializer(),

      el = attrs.iterateNext(),
      act = el.attributes,

      i = act.length,
      _l = i,
      _nodeArr = [],
      _nodeArrKeys = [],
      name;

  console.log(serializer.serializeToString(el));

  for (i ;i--;) {
    name = act[i].nodeName;
    _nodeArr[name] = (act.removeNamedItem(name));
    _nodeArrKeys[i] = name;
  }

  _nodeArrKeys = _nodeArrKeys.sort();
  i++;

  for (i;_l>i;i++) {
    act.setNamedItem(_nodeArr[_nodeArrKeys[i]]);
  }

  console.log(serializer.serializeToString(el));
})();

控制台日志输出

<td zataa="123" bbbrowspan="2" cccattr="val" aaacolspan="2">Cell 1,1
                    <br>Cell 2,1
                    <br>Cell 1,2
                    <br>Cell 2,2</td>

<td aaacolspan="2" bbbrowspan="2" cccattr="val" zataa="123">Cell 1,1
                    <br>Cell 2,1
                    <br>Cell 1,2
                    <br>Cell 2,2</td> 

【讨论】:

    【解决方案2】:

    如果你真的必须...试试这个fiddle
    不过我不得不说,我真的很好奇你为什么要这样做。

    代码:

    var elements = document.getElementsByTagName("*");
    sortAttributes(elements);
    
    //From: http://stackoverflow.com/questions/979256/how-to-sort-an-array-of-javascript-objects
    function sortBy(field, reverse, primer) {
        var key = function(x) {
            return primer ? primer(x[field]) : x[field];
        };
    
        return function(a, b) {
            var A = key(a),
                B = key(b);
            return ((A < B) ? -1 : (A > B) ? +1 : 0) * [-1, 1][+ !! reverse];
        }
    };
    
    function sortAttributes(elements) {
        for (var j = 0; j < elements.length; j++) {
            var attributes = [];
            for (var i = 0; i < elements[j].attributes.length; i++) {
                attributes.push({
                    'name': elements[j].attributes[i].name,
                    'value': elements[j].attributes[i].value
                });
            }
    
            var sortedAttributes = attributes.sort(sortBy('name', true, function(a) {
                return a.toUpperCase();
            }));
    
            for (var i = 0; i < sortedAttributes.length; i++) {
                $(elements[j]).removeAttr(sortedAttributes[i]['name']);
            }
    
            for (var i = 0; i < sortedAttributes.length; i++) {
                $(elements[j]).attr(sortedAttributes[i]['name'], sortedAttributes[i]['value']);
            }
        }
    }
    

    【讨论】:

    • 感谢这项工作。我需要这个的原因是我正在对 2 组 HTML 进行比较,并且属性顺序正在破坏它。
    • 我只是在想,我能想到这样做的唯一原因是如果你要运行距离算法......然后你确认了它。 :)
    • 它可能适用于某些浏览器,但浏览器没有义务按照设置的顺序返回属性。
    • 没错,但他们也没有义务不这样做。话虽如此,dmi3y 可能有更好的解决方案,因为它将问题完全从浏览器中抽象出来,而且毫无疑问运行得更快。
    • 我几乎要投票了,但你回答了一个 JavaScript 问题,但没有必要的库先决条件。
    【解决方案3】:

    只需使用Prettydiff。它会在美化您的 HTML 时按字母顺序对属性进行排序。它是用 JavaScript 编写的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 2010-11-24
      • 1970-01-01
      相关资源
      最近更新 更多