Jak normalizować HTML w JavaScript lub jQuery?

Znaczniki mogą mieć wiele atrybutów. Kolejność w jakiej atrybuty pojawiają się w kodzie nie ma znaczenia. Na przykład:

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

Jak mogę "normalizować" HTML w Javascript, aby kolejność atrybutów była zawsze taka sama? Nie obchodzi mnie, która kolejność zostanie wybrana, o ile zawsze jest taka sama.

UPDATE : moim pierwotnym celem było ułatwienie różnicowania (w JavaScript) 2 stron HTML z niewielkimi różnicami. Ponieważ użytkownicy mogą używać innego oprogramowania do edycji kod, kolejność atrybutów może ulec zmianie. To sprawia, że różnica jest zbyt gadatliwa.

Odpowiedź: cóż, najpierw dzięki za wszystkie odpowiedzi. I tak, jest to możliwe. Oto jak udało mi się to zrobić. Jest to dowód koncepcji, z pewnością można ją zoptymalizować: {]}

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

To samo dla drugiego elementu Diffa, $('#different'). Teraz $('#original').html() i $('#different').html() Pokaż kod HTML z atrybutami w tej samej kolejności.

Author: Julien, 2010-10-20

8 answers

JavaScript nie widzi strony internetowej w postaci tekstowego HTML, ale raczej jako strukturę drzewiastą znaną jako DOM lub model obiektowy dokumentu. Kolejność atrybutów elementów HTML w DOM nie jest zdefiniowana (w rzeczywistości, jak w komentarzach Svend, nie są one nawet częścią DOM), więc pomysł sortowania ich w punkcie, w którym działa JavaScript jest nieistotny.

Mogę tylko zgadywać, co próbujesz osiągnąć. Jeśli próbujesz to zrobić, aby poprawić wydajność JavaScript/strony, większość HTML rendererzy dokumentów już prawdopodobnie włożyli wiele wysiłku w optymalizację dostępu do atrybutów, więc niewiele można tam zyskać.

Jeśli próbujesz zamówić atrybuty, aby kompresja gzip stron była bardziej efektywna, ponieważ są wysyłane przez przewód, zrozum, że JavaScript działa po tym punkcie w czasie. Zamiast tego możesz chcieć spojrzeć na rzeczy, które działają po stronie serwera, chociaż prawdopodobnie jest to więcej kłopotów niż jest warte.

 68
Author: Tung Nguyen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-21 02:27:59

Weź HTML i parse do struktury DOM. Następnie weź strukturę DOM i zapisz ją z powrotem do HTML. Podczas pisania posortuj atrybuty używając dowolnego stabilnego sortowania. Twój HTML zostanie teraz znormalizowany w odniesieniu do atrybutów.

Jest to ogólny sposób na normalizację rzeczy. (parse unormalized data, then write it back out in unormalized form).

Nie jestem pewien, dlaczego chcesz normalizować HTML, ale masz to. Data to data. ;-)

 35
Author: Kim Bruning,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-20 11:53:36

Jest to dowód koncepcji, z pewnością można ją zoptymalizować:

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

To samo dla drugiego elementu różnicy, $('#different'). Teraz $('#original').html() i $('#different').html () pokazuje kod HTML z atrybutami w tej samej kolejności.

 12
Author: Julien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-22 19:42:16

Możesz spróbować otworzyć kartę HTML w firebug, atrybuty są zawsze w tej samej kolejności

 8
Author: tsurahman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-20 06:13:04

Właściwie, mogę wymyślić kilka dobrych powodów. Jednym z nich byłoby porównanie dla dopasowania tożsamości i do użycia z narzędziami typu "diff", gdzie jest dość irytujące, że semantycznie równoważne linie mogą być oznaczone jako "różne".

Prawdziwe pytanie brzmi "dlaczego w Javascript"?

To pytanie "pachnie" "mam problem i chyba mam odpowiedź...ale ja też mam problem z odpowiedzią."

Jeśli OP wyjaśni Dlaczego chcą to zrobić, ich szanse na uzyskanie dobrej odpowiedzi wzrosłoby dramatycznie.

 5
Author: Snowhare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-20 19:42:13

Pytanie " Jaka jest tego potrzeba?" Odpowiedź: sprawia, że kod jest bardziej czytelny i łatwiejszy do zrozumienia.

Dlaczego większość UI jest do bani... Wielu programistów nie rozumie potrzeby upraszczania zadań użytkowników. W tym przypadku zadaniem użytkowników jest czytanie i zrozumienie kodu. Jednym z powodów, aby zamówić atrybuty jest dla człowieka, który musi debugować i utrzymywać kod. Uporządkowana lista, z którą program zapoznaje, ułatwia mu pracę. Może szybciej znaleźć atrybuty lub uświadom sobie, których atrybutów brakuje, i szybciej zmieniaj wartości atrybutów.

 2
Author: signedbit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-20 18:18:42

To ma znaczenie tylko wtedy, gdy ktoś czyta źródło, więc dla mnie najpierw są atrybuty semantyczne, potem mniej semantyczne...

Są oczywiście wyjątki, jeśli masz na przykład kolejne

  • 's, wszystkie z jednym atrybutem na każdym i inne tylko na niektórych, możesz chcieć upewnić się, że wspólne są wszystkie na początku, a następnie pojedyncze, np.

    A

  • B
  • C

    (nawet jeśli atrybut " b " jest bardziej semantycznie użyteczne niż "a")

    Masz pomysł.

  •  0
    Author: Ali,
    Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
    2010-10-20 19:03:33

    Wydaje mi się, że jest to możliwe, jeśli zawartość html jest przekazywana jako xml i renderowana przez xslt... dlatego oryginalna treść w XML może być w dowolnej kolejności.

     0
    Author: Nasaralla,
    Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
    2011-10-06 14:36:53