web-dev-qa-db-ja.com

JavaScriptまたはjQueryでHTMLを正規化する方法は?

タグには複数の属性を設定できます。コードに属性が表示される順序は重要ではありません。例えば:

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

JavascriptでHTMLを「正規化」するにはどうすれば属性の順序が常に同じになりますか?順序が常に同じである限り、どの順序が選択されてもかまいません。

[〜#〜] update [〜#〜]:私の当初の目標は、わずかな違いのある2つのHTMLページを(JavaScriptで)簡単に比較できるようにすることでした。ユーザーは異なるソフトウェアを使用してコードを編集できるため、属性の順序が変わる可能性があります。これにより、差分が冗長になりすぎます。

[〜#〜] answer [〜#〜]:すべての回答に感謝します。はい、可能です。これが私がどうやってそれをやったかです。これは概念実証であり、確実に最適化できます。

_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の2番目の要素$('#different')についても同様です。 $('#original').html()$('#different').html()は、同じ順序で属性を持つHTMLコードを表示するようになりました。

83
Julien

これは概念実証であり、確実に最適化できます。

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の2番目の要素$( '#different')についても同じことが言えます。これで、$( '#original')。html()および$( '#different')。html()は同じ順序で属性を持つHTMLコードを表示します。

12
Julien

JavaScriptは、実際にはテキストベースのHTML形式のWebページではなく、DOMまたはドキュメントオブジェクトモデルとして知られるツリー構造として表示されます。 DOMのHTML要素属性の順序は定義されていません(実際、Svendコメントとして、それらはDOMの一部ではありません)。したがって、JavaScriptが実行されるポイントでそれらをソートするという考えは無関係です。

私はあなたが達成しようとしているものしか推測できません。 JavaScript /ページのパフォーマンスを改善するためにこれを行おうとしている場合、ほとんどのHTMLドキュメントレンダラーはすでに属性アクセスの最適化に多大な労力を費やしているので、そこにはほとんど何も得られません。

ページをgzipで圧縮してネットワーク経由で送信するときの効率を高めるために属性を注文しようとしている場合は、その時点以降にJavaScriptが実行されることを理解してください。代わりに、サーバー側で実行されるものを代わりに見たいと思うかもしれませんが、おそらくそれは価値があるよりも厄介です。

68
Tung Nguyen

HTMLを取得し、DOM構造に解析します。次に、DOM構造を取得し、HTMLに書き戻します。書き込み中に、安定したソートを使用して属性をソートします。これで、HTMLが属性に関して正規化されます。

これは、物事を正規化する一般的な方法です。 (正規化されていないデータを解析し、正規化された形式で書き戻します)。

HTMLを正規化する理由がわかりませんが、そこにあります。データはデータです。 ;-)

35
Kim Bruning

firebugでHTMLタブを開くことができます。属性は常に同じ順序です

8
tsurahman

実際、いくつかの正当な理由を考えることができます。 1つは、IDマッチングの比較と、セマンティック上同等の行を「異なる」とマークできることが非常に迷惑な「diff」タイプのツールでの使用です。

本当の質問は「なぜJavascriptで」ですか?

この質問は「私には問題があり、答えがあると思うが...答えにも問題がある」という「臭い」です。

OPがwhyを説明したい場合、適切な回答を得る可能性が劇的に上がります。

5
Snowhare

「これの必要性は何ですか?」という質問回答:コードを読みやすく、理解しやすくします。

ほとんどのUIが悪い理由...多くのプログラマーは、ユーザーの仕事を簡素化する必要性を理解していません。この場合、ユーザーの仕事はコードを読んで理解することです。属性を順序付ける理由の1つは、コードをデバッグおよび保守する必要がある人間のためです。プログラムが使い慣れた順序付きリストにより、仕事が楽になります。彼はより迅速に属性を見つけたり、どの属性が欠落しているかを認識したり、より迅速に属性値を変更したりできます。

2
signedbit

htmlコンテンツがxmlとして渡され、xsltを介してレンダリングされる場合、実際には可能だと思います。したがって、XMLの元のコンテンツは任意の順序にできます。

0
Nasaralla

これは、誰かがソースを読んでいるときにのみ問題になるので、私にとっては最初にセマンティック属性であり、次にセマンティック属性ではありません...

もちろん、例外があります。たとえば、連続した<li>があり、すべてがそれぞれに1つの属性を持ち、他の属性が一部のみにある場合、共有の属性がすべて先頭にあり、その後に個別の属性が続くことを確認できます。 。

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

(「b」属性が「a」よりも意味的に有用であっても)

あなたはアイデアを得る。

0
Ali