admin管理员组

文章数量:1415111

How would I sort HTML attributes using JavaScript?

I have this 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>

And I want to sort all attribute in all elements into alphabetical order. E.g:

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

The sort function could either be based on a HTML string, or a jQuery object, or a node (it doesn't matter which one).

The reason I need this is because I am doing a diff (with JS, in the browser, after a failed unit test) between 2 sets of HTML and the attribute order is making it fail.

So my questions are:

How can I reorder a nodes attributes?, Or how can I reorder attributes in an HTML string?, Or how can I reorder a jQuery elements attributes?

I haven't got any code for it yet, as I am unsure which method would be the best.

How would I sort HTML attributes using JavaScript?

I have this 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>

And I want to sort all attribute in all elements into alphabetical order. E.g:

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

The sort function could either be based on a HTML string, or a jQuery object, or a node (it doesn't matter which one).

The reason I need this is because I am doing a diff (with JS, in the browser, after a failed unit test) between 2 sets of HTML and the attribute order is making it fail.

So my questions are:

How can I reorder a nodes attributes?, Or how can I reorder attributes in an HTML string?, Or how can I reorder a jQuery elements attributes?

I haven't got any code for it yet, as I am unsure which method would be the best.

Share Improve this question edited Dec 7, 2012 at 6:25 Petah asked Dec 6, 2012 at 21:26 PetahPetah 46.1k30 gold badges160 silver badges215 bronze badges 16
  • 13 More importantly, why do you want to do this? – Colleen Commented Dec 6, 2012 at 21:28
  • 3 What you're describing is pointless and almost nonsensical. Attributes don't have an "order" at all. If you want them ordered in your HTML source, then this really doesn't have a lot to do with JavaScript unless your editor/IDE has a built-in JavaScript interpreter. – Pointy Commented Dec 6, 2012 at 21:34
  • 3 @Diodeus — It's a coding style. There are arguments to be made in its favour. – Quentin Commented Dec 6, 2012 at 22:37
  • 1 @Colleen because I am doing a diff on 2 sets of HTML, and the attribute order is breaking it. – Petah Commented Dec 7, 2012 at 0:35
  • 1 @GGG because I am doing a diff on 2 sets of HTML, and the attribute order is breaking it. – Petah Commented Dec 7, 2012 at 0:35
 |  Show 11 more ments

3 Answers 3

Reset to default 3

Have no idea why you need do this with javascript, but it was rather interested. Okay, according spec:

Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes.

So you could order by changing numeral index, after a while there is my attempt which works smooth in 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));
})();

console log output

<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> 

If you really must... try this fiddle.
I have to say though, I'm really curious why you would want to do this.

Code:

var elements = document.getElementsByTagName("*");
sortAttributes(elements);

//From: http://stackoverflow./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']);
        }
    }
}

Just use Prettydiff. It will sort attributes alphabetically when it beautifies your HTML. It is written in JavaScript.

本文标签: Sort HTML attributes with JavaScriptStack Overflow