Jak znormalizować HTML w JavaScript lub jQuery?


84

Tagi 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ę „znormalizować” kod HTML w JavaScript, aby kolejność atrybutów była zawsze taka sama? Nie obchodzi mnie, która kolejność jest wybrana, o ile zawsze jest taka sama.

UPDATE : moim pierwotnym celem było ułatwienie porównywania (w JavaScript) 2 stron HTML z niewielkimi różnicami. Ponieważ użytkownicy mogą używać innego oprogramowania do edycji kodu, kolejność atrybutów może się zmienić. To sprawia, że ​​różnica jest zbyt szczegółowa.

ODPOWIEDŹ : Cóż, po pierwsze dzięki za wszystkie odpowiedzi. I TAK, jest to możliwe. Oto, jak mi się to udało. To jest dowód słuszności koncepcji, z pewnością można go 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 diff, $('#different'). Teraz $('#original').html()i $('#different').html()pokaż kod HTML z atrybutami w tej samej kolejności.


59
Jaka jest tego potrzeba?
rahul

40
@rahul: w rzeczywistości istnieje całkiem interesująca potrzeba: może to znacznie poprawić kompresję gzip twoich stron.
haylem

11
ach, w Javascript ... tyle jeśli chodzi o kompresję. Nie mam pojęcia, jaka jest wtedy potrzeba.
haylem

13
@Julien: Do czasu uruchomienia kodu JavaScript strona została już wysłana do klienta. Nie wiem, jak to może pomóc w kompresji.
casablanca

22
W rzeczywistości próba robienia tego, o co prosi OP, ma sens. Używanie edytora WYSIWYG do prowadzenia wiki. Projekt, nad którym pracuję, robi dokładnie to, a edytor odwracał kolejność atrybutów za każdym razem, gdy edytowałeś wiki, powodując niepotrzebne różnice. Skończyło się na alfabetycznym sortowaniu atrybutów w przesłanym kodzie HTML na zapleczu przed zapisaniem, aby uniknąć różnic; mógł równie łatwo zrobić to sortowanie w javascript przed przesłaniem.
Frank Farmer,

Odpowiedzi:


68

JavaScript w rzeczywistości nie widzi strony internetowej w postaci opartego na tekście HTML, ale raczej jako strukturę drzewa znaną jako DOM lub Document Object Model. Kolejność atrybutów elementów HTML w DOM nie jest zdefiniowana (w rzeczywistości, jak komentuje Svend, nie są one nawet częścią DOM), więc pomysł sortowania ich w miejscu, 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ść programów renderujących dokumenty HTML prawdopodobnie już włożyła dużo wysiłku w optymalizację dostępu do atrybutów, więc niewiele można tam zyskać.

Jeśli próbujesz uporządkować atrybuty, aby kompresja Gzip stron była bardziej skuteczna, gdy są one przesyłane przez sieć, pamiętaj, że JavaScript działa po tym momencie. Zamiast tego możesz spojrzeć na rzeczy, które działają po stronie serwera, chociaż prawdopodobnie jest to więcej kłopotów niż jest warte.


8
JavaScript może działać po stronie serwera.
Matt Kantor

Atrybuty nie są uważane za część drzewa dokumentu (w którym porządek jest naturalny). Więc chociaż Attr dziedziczy interfejs Node, DOM Core 2 określa te pola jako puste dla atrybutów w3.org/TR/DOM-Level-2-Core/core.html#ID-637646024
Svend

35

Weź HTML i przeanalizuj 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 kod HTML zostanie teraz znormalizowany pod względem atrybutów.

To jest ogólny sposób normalizacji rzeczy. (analizuje dane nieznormalizowane, a następnie zapisuje je z powrotem w znormalizowanej formie).

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


1
Czy masz przykład kodu. Próbowałem zrobić coś podobnego, nie udało się.
Julien

12

To jest dowód słuszności koncepcji, z pewnością można go 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 dotyczy drugiego elementu różnicy, $ ('# inny'). Teraz $ ('# oryginał'). Html () i $ ('# inny'). Html () pokazują kod HTML z atrybutami w tej samej kolejności.


Myślę, że lepiej, jeśli wygenerujesz zawartość HTML w XML, a następnie wyrenderujesz ją za pomocą xslt. Z pewnością uzyskasz ładniejszy wynik.
Nasaralla

8

możesz spróbować otworzyć zakładkę HTML w firebugu, atrybuty są zawsze w tej samej kolejności


4
To nie jest samo w sobie pomocne. Dzieje się tak, ponieważ odtwarza kod HTML z DOM, a jakkolwiek to się dzieje, ma określoną kolejność iteracji atrybutów (lub Firebug sortuje je ręcznie). Julien mógłby to wykorzystać i użyć tej samej metody do napisania HTML.
Matt Kantor

5

Właściwie przychodzi mi do głowy kilka dobrych powodów. Jednym z nich byłoby porównanie do dopasowywania tożsamości i do użytku z narzędziami typu „diff”, gdzie jest dość denerwujące, że semantycznie równoważne wiersze można oznaczyć jako „różne”.

Prawdziwe pytanie brzmi: „Dlaczego w Javascript”?

To pytanie „pachnie” „Mam problem i myślę, że mam odpowiedź… ale mam też problem z odpowiedzią”.

Gdyby PO wyjaśnił, dlaczego chcą to zrobić, ich szanse na uzyskanie dobrej odpowiedzi wzrosłyby dramatycznie.


2

Pytanie „Jaka jest tego potrzeba?” Odpowiedź: Dzięki temu kod jest bardziej czytelny i łatwiejszy do zrozumienia.

Dlaczego większość interfejsu użytkownika jest do niczego ... Wielu programistów nie rozumie potrzeby upraszczania pracy użytkowników. W tym przypadku zadaniem użytkownika jest odczyt i zrozumienie kodu. Jednym z powodów porządkowania atrybutów jest osoba, która musi debugować i utrzymywać kod. Uporządkowana lista, z którą zapoznaje się program, ułatwia mu pracę. Potrafi szybciej znaleźć atrybuty lub zorientować się, których atrybutów brakuje, i szybciej zmienić wartości atrybutów.


Wydaje mi się, że nie myślałeś o tym pytaniu wystarczająco długo; nawet działające rozwiązanie tego pytania nie rozwiązałoby tego, co tu mówisz, chociaż może tak być.
issa marie tseng

Dlaczego przypuszczasz, że OP chciałby to zrobić z Javascriptem? Jest możliwe , że po stronie serwera (czas budowy?) Rozwiązanie Javascript był w umyśle, ale jest mało prawdopodobne, że ktoś doświadczył tyle do zrobienia, że nie udało się wymienić go na stanowisku Stackoverflow. Możliwe jest również, że OP implementuje edytor HTML w przeglądarce, ale to również wydaje się wątpliwe.
Pointy

0

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

Oczywiście są wyjątki, jeśli masz na przykład kolejne <li>, wszystkie z jednym atrybutem na każdym, a inne tylko na niektórych, możesz chcieć upewnić się, że wszystkie udostępnione są na początku, a następnie indywidualne, np. .

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

(Nawet jeśli atrybut „b” jest bardziej użyteczny semantycznie niż „a”)

Masz pomysł.


0

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.