Wie normalisiere ich HTML in JavaScript oder jQuery?

84

Tags können mehrere Attribute haben. Die Reihenfolge, in der Attribute im Code angezeigt werden, spielt keine Rolle. Beispielsweise:

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

Wie kann ich den HTML-Code in Javascript "normalisieren", damit die Reihenfolge der Attribute immer gleich ist? Es ist mir egal, welche Reihenfolge gewählt wird, solange es immer dieselbe ist.

UPDATE : Mein ursprüngliches Ziel war es, das Diff (in JavaScript) von 2 HTML-Seiten mit geringfügigen Unterschieden zu vereinfachen. Da Benutzer zum Bearbeiten des Codes unterschiedliche Software verwenden können, kann sich die Reihenfolge der Attribute ändern. Dies macht den Unterschied zu ausführlich.

ANTWORT : Nun, zuerst danke für alle Antworten. Und JA, es ist möglich. Hier ist, wie ich es geschafft habe. Dies ist ein Proof of Concept, der durchaus optimiert werden kann:

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);
    }
  }
});

Gleiches gilt für das zweite Element des Diff $('#different'). Jetzt $('#original').html()und $('#different').html()zeigt HTML - Code mit Attributen in der gleichen Reihenfolge.

Julien
quelle
59
Was ist die Notwendigkeit dafür?
Rahul
40
@rahul: Eigentlich gibt es dafür einen ziemlich interessanten Bedarf: Es kann die gzip-Komprimierung Ihrer Seiten erheblich verbessern.
Haylem
11
ah, in Javascript ... so viel zur Komprimierung. Keine Ahnung, was dann nötig ist.
Haylem
13
@ Julien: Zum Zeitpunkt der Ausführung Ihres JavaScript-Codes wurde die Seite bereits an den Client gesendet. Ich sehe nicht, wie es dann bei der Komprimierung helfen kann.
Casablanca
22
Es gibt tatsächlich eine gültige Verwendung für den Versuch, das zu tun, was das OP verlangt. Verwenden eines WYSIWYG-Editors zum Fahren eines Wikis. Das Projekt, an dem ich arbeite, macht genau das und der Editor kehrt die Reihenfolge der Attribute jedes Mal um, wenn Sie das Wiki bearbeiten, was zu unnötigen Unterschieden führt. Am Ende sortiere ich die Attribute im übermittelten HTML-Code im Backend alphabetisch, bevor ich sie speichere, um Unterschiede zu vermeiden. hätte diese Sortierung genauso einfach in Javascript durchführen können, bevor sie eingereicht wurde.
Frank Farmer

Antworten:

68

JavaScript sieht eine Webseite nicht in Form von textbasiertem HTML, sondern als Baumstruktur, die als DOM oder Document Object Model bezeichnet wird. Die Reihenfolge der HTML-Elementattribute im DOM ist nicht definiert (tatsächlich sind sie, wie Svend kommentiert, nicht einmal Teil des DOM), sodass die Idee, sie an dem Punkt zu sortieren, an dem JavaScript ausgeführt wird, irrelevant ist.

Ich kann nur raten, was Sie erreichen wollen. Wenn Sie dies versuchen, um die Leistung von JavaScript / Seiten zu verbessern, haben die meisten HTML-Dokumentrenderer vermutlich bereits große Anstrengungen unternommen, um den Attributzugriff zu optimieren, sodass dort wenig zu gewinnen ist.

Wenn Sie versuchen, Attribute zu bestellen, um die GZIP-Komprimierung von Seiten beim Senden über das Netzwerk effektiver zu gestalten, sollten Sie verstehen, dass JavaScript nach diesem Zeitpunkt ausgeführt wird. Stattdessen möchten Sie vielleicht Dinge betrachten, die stattdessen serverseitig ausgeführt werden, obwohl es wahrscheinlich mehr Probleme gibt, als es wert ist.

Tung Nguyen
quelle
8
JavaScript kann serverseitig ausgeführt werden.
Matt Kantor
Attribute werden nicht als Teil des Dokumentbaums betrachtet (der natürlich die Reihenfolge verwendet). Während Attr die Knotenschnittstelle erbt, gibt DOM Core 2 an, dass diese Felder für die Attribute w3.org/TR/DOM-Level-2-Core/core.html#ID-637646024
Svend
35

Nehmen Sie den HTML-Code und analysieren Sie ihn in eine DOM-Struktur. Nehmen Sie dann die DOM-Struktur und schreiben Sie sie wieder in HTML aus. Sortieren Sie die Attribute beim Schreiben mit einer beliebigen stabilen Sortierung. Ihr HTML wird nun in Bezug auf Attribute normalisiert.

Dies ist ein allgemeiner Weg, um Dinge zu normalisieren. (Analysieren Sie nicht normalisierte Daten und schreiben Sie sie dann in normalisierter Form zurück.)

Ich bin mir nicht sicher, warum Sie HTML normalisieren möchten, aber da haben Sie es. Daten sind Daten. ;-);

Kim Bruning
quelle
1
Haben Sie ein Codebeispiel? Ich habe versucht, etwas Ähnliches zu tun, es hat nicht funktioniert.
Julien
12

Dies ist ein Proof of Concept, der durchaus optimiert werden kann:

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);
    }
  }
 });

Gleiches gilt für das zweite Element des Diff, $ ('# different'). Jetzt zeigen $ ('# original'). Html () und $ ('# different'). Html () HTML-Code mit Attributen in derselben Reihenfolge.

Julien
quelle
Ich denke besser, wenn Sie Ihre HTML-Inhalte in XML generieren und dann mit xslt rendern. Sie werden sicherlich eine schönere Ausgabe erhalten.
Nasaralla
8

Sie können versuchen, die HTML-Registerkarte in Firebug zu öffnen. Die Attribute sind immer in derselben Reihenfolge

Tsurahman
quelle
4
Dies ist für sich genommen nicht wirklich hilfreich. Dies liegt daran, dass der HTML-Code aus dem DOM neu erstellt wird. Dies geschieht jedoch mit einer bestimmten Attribut-Iterationsreihenfolge (oder Firebug sortiert sie manuell). Julien könnte dies nutzen und dieselbe Methode verwenden, um HTML zu schreiben.
Matt Kantor
5

Eigentlich kann ich mir ein paar gute Gründe vorstellen. Ein Vergleich wäre der Identitätsabgleich und die Verwendung mit Werkzeugen vom Typ "diff", bei denen es ziemlich ärgerlich ist, dass semantisch äquivalente Zeilen als "unterschiedlich" markiert werden können.

Die eigentliche Frage ist "Warum in Javascript"?

Diese Frage "riecht" nach "Ich habe ein Problem und ich glaube, ich habe eine Antwort ... aber ich habe auch ein Problem mit meiner Antwort."

Wenn das OP erklären würde, warum sie dies tun wollen, würden ihre Chancen auf eine gute Antwort dramatisch steigen.

Schneehase
quelle
2

Die Frage "Was ist die Notwendigkeit dafür?" Antwort: Dadurch wird der Code besser lesbar und verständlicher.

Warum die meisten Benutzeroberflächen scheiße sind ... Viele Programmierer verstehen nicht, wie wichtig es ist, den Benutzerjob zu vereinfachen. In diesem Fall liest und versteht der Benutzer den Code. Ein Grund, die Attribute zu bestellen, ist für den Menschen, der den Code debuggen und pflegen muss. Eine geordnete Liste, mit der das Programm vertraut wird, erleichtert seine Arbeit. Er kann Attribute schneller finden oder erkennen, welche Attribute fehlen, und Attributwerte schneller ändern.

signiertes Bit
quelle
Denken Sie, Sie haben nicht lange genug über die Frage nachgedacht; Selbst eine funktionierende Lösung für die Frage würde nicht das ansprechen, was Sie hier sagen, auch wenn es wahr sein mag.
Issa Marie Tseng
Warum sollte das OP dies mit Javascript tun? Es ist möglich, dass eine serverseitige (Build-Zeit?) Javascript-Lösung in Betracht gezogen wurde, aber es ist unwahrscheinlich, dass jemand, der genug Erfahrung damit hat, dies in einem Stackoverflow-Beitrag nicht erwähnt hätte. Es ist auch möglich, dass das OP einen HTML-Editor im Browser implementiert, aber das scheint auch zweifelhaft.
Pointy
0

Dies ist nur wichtig, wenn jemand die Quelle liest. Für mich sind es also zuerst semantische Attribute, dann weniger semantische ...

Es gibt natürlich Ausnahmen. Wenn Sie beispielsweise aufeinanderfolgende <li> haben, alle mit einem Attribut für jedes und andere nur für einige, möchten Sie möglicherweise sicherstellen, dass die gemeinsam genutzten am Anfang stehen, gefolgt von einzelnen, z .

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

(Auch wenn das Attribut "b" semantisch nützlicher ist als "a")

Du hast die Idee.

Ali
quelle
0

Ich denke, es ist tatsächlich möglich, wenn der HTML-Inhalt als XML übergeben und über xslt gerendert wird. Daher kann Ihr ursprünglicher Inhalt in XML in beliebiger Reihenfolge vorliegen.

Nasaralla
quelle