如何在 JavaScript 或 jQuery 中规范化 HTML?

标签可以有多个属性。属性在代码中出现的顺序并不重要。例如:

<a href="#" title="#">
<a title="#" href="#">

我如何“规范化”Javascript 中的 HTML,使属性的顺序始终相同?我不在乎选择哪个顺序,只要它总是相同的。

UPDATE : 我最初的目标是使(在 JavaScript 中)2个 HTML 页面之间的细微差异更容易区分。因为用户可以使用不同的软件来编辑代码,所以属性的顺序可能会发生变化。这使得差异太冗长。

答案 : 好吧,首先感谢所有的答案。是的,这是可能的。我是这样做的。这是一个概念的证明,它当然可以被优化:

function sort_attributes(a, b) {
if( a.name == b.name) {
return 0;
}


return (a.name < b.name) ? -1 : 1;
}


$("#original").find('*').each(function() {
if (this.attributes.length > 1) {
var attributes = this.attributes;
var list = [];


for(var i =0; i < attributes.length; i++) {
list.push(attributes[i]);
}


list.sort(sort_attributes);


for(var i = 0; i < list.length; i++) {
this.removeAttribute(list[i].name, list[i].value);
}


for(var i = 0; i < list.length; i++) {
this.setAttribute(list[i].name, list[i].value);
}
}
});

对于 diff 的第二个元素 $('#different')也是如此。现在,$('#original').html()$('#different').html()以相同的顺序显示具有属性的 HTML 代码。

72897 次浏览

you can try open HTML tab in firebug, the attributes are always in same order

JavaScript doesn't actually see a web page in the form of text-based HTML, but rather as a tree structure known as the DOM, or Document Object Model. The order of HTML element attributes in the DOM is not defined (in fact, as Svend comments, they're not even part of the DOM), so the idea of sorting them at the point where JavaScript runs is irrelevant.

I can only guess what you're trying to achieve. If you're trying to do this to improve JavaScript/page performance, most HTML document renderers already presumably put a lot of effort into optimising attribute access, so there's little to be gained there.

If you're trying to order attributes to make gzip compression of pages more effective as they're sent over the wire, understand that JavaScript runs after that point in time. Instead, you may want to look at things that run server-side instead, though it's probably more trouble than it's worth.

Take the HTML and parse into a DOM structure. Then take the DOM structure, and write it back out to HTML. While writing, sort the attributes using any stable sort. Your HTML will now be normalized with regard to attributes.

This is a general way to normalize things. (parse non-normalized data, then write it back out in normalized form).

I'm not sure why you'd want to Normalize HTML, but there you have it. Data is data. ;-)

The question "What is the need for this?" Answer: It makes the code more readable and easier to understand.

Why most UI sucks... Many programmers fail to understand the need for simplifying the users job. In this case, the users job is reading and understanding the code. One reason to order the attributes is for the human who has to debug and maintain the code. An ordered list, which the program becomes familiar with, makes his job easier. He can more quickly find attributes, or realize which attributes are missing, and more quickly change attribute values.

This only matters when someone is reading the source, so for me it's semantic attributes first, less semantic ones next...

There are exceptions of course, if you have for example consecutive <li>'s, all with one attribute on each and others only on some, you may want to ensure the shared ones are all at the start, followed by individual ones, eg.

<li a="x">A</li>
<li a="y" b="t">B</li>
<li a="z">C</li>

(Even if the "b" attribute is more semantically useful than "a")

You get the idea.

Actually, I can think of a few good reasons. One would be comparison for identity matching and for use with 'diff' type tools where it is quite annoying that semantically equivalent lines can be marked as "different".

The real question is "Why in Javascript"?

This question "smells" of "I have a problem and I think I have an answer...but I have a problem with my answer, too."

If the OP would explain why they want to do this, their chances of getting a good answer would go up dramatically.

This is a proof of concept, it can certainly be optimized:

function sort_attributes(a, b) {
if( a.name == b.name) {
return 0;
}


return (a.name < b.name) ? -1 : 1;
}


$("#original").find('*').each(function() {
if (this.attributes.length > 1) {
var attributes = this.attributes;
var list = [];


for(var i =0; i < attributes.length; i++) {
list.push(attributes[i]);
}


list.sort(sort_attributes);


for(var i = 0; i < list.length; i++) {
this.removeAttribute(list[i].name, list[i].value);
}


for(var i = 0; i < list.length; i++) {
this.setAttribute(list[i].name, list[i].value);
}
}
});

Same thing for the second element of the diff, $('#different'). Now $('#original').html() and $('#different').html() show HTML code with attributes in the same order.

it is actually possible, I think, if the html contents are passed as xml and rendered through xslt... therefore your original content in XML can be in whatever order you want.