Як нормалізувати HTML в JavaScript або jQuery?


84

Теги можуть мати кілька атрибутів. Порядок появи атрибутів у коді не має значення. Наприклад:

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

Як я можу "нормалізувати" HTML у Javascript, так що порядок атрибутів завжди однаковий? Мені байдуже, який порядок обраний, якщо він завжди однаковий.

ОНОВЛЕННЯ : моєю початковою метою було полегшити розрізнення (у 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);
    }
  }
});

Те ж саме для другого елементу диференціала, $('#different'). Тепер $('#original').html()і $('#different').html()показати HTML код з атрибутами в тому ж порядку.


59
Що для цього потрібно?
rahul

40
@rahul: насправді в цьому є досить цікава потреба: це може значно покращити стиснення gzip ваших сторінок.
haylem

11
ах, у Javascript ... так багато для стиснення. Поняття не маю, у чому тоді потреба.
haylem

13
@Julien: На момент запуску вашого коду JavaScript сторінка вже була відправлена ​​клієнту. Я не розумію, як тоді це може допомогти при стисненні.
casablanca

22
Насправді існує сприятливе використання для спроб зробити те, що запитує OP. Використання редактора WYSIWYG для керування вікі. Проект, над яким я працюю, робить саме це, і редактор змінює порядок атрибутів кожного разу, коли ви редагували вікі, що призводить до непотрібних відмінностей. Я закінчую в алфавітному порядку сортування атрибутів у поданому HTML на серверній панелі перед збереженням, щоб уникнути відмінностей; міг так само легко зробити це сортування у javascript перед подачею.
Frank Farmer

Відповіді:


68

JavaScript насправді не бачить веб-сторінку у вигляді текстового HTML, а скоріше як деревоподібну структуру, відому як DOM, або об'єктна модель документа. Порядок атрибутів елементів HTML у DOM не визначений (насправді, як зауважує Свенд, вони навіть не є частиною DOM), тому ідея сортувати їх у точці, де працює JavaScript, неактуальна.

Я можу лише здогадуватися, чого ви намагаєтесь досягти. Якщо ви намагаєтеся зробити це, щоб поліпшити продуктивність JavaScript / сторінки, більшість рендеристів HTML-документів вже, мабуть, докладають багато зусиль для оптимізації доступу до атрибутів, тому тут мало що можна отримати.

Якщо ви намагаєтеся впорядкувати атрибути, щоб зробити стиснення gzip сторінок більш ефективним, оскільки вони надсилаються по дроту, розумійте, що JavaScript запускається після цього моменту часу. Натомість вам може знадобитися розглянути речі, які працюють на стороні сервера, натомість це, мабуть, більше проблем, ніж це варте.


8
JavaScript може працювати на стороні сервера.
Метт Кантор,

Атрибути не вважаються частиною дерева документів (що впорядковує природно). Отже, поки Attr успадковує інтерфейс Node, DOM Core 2 визначає ці поля як нульові для атрибутів w3.org/TR/DOM-Level-2-Core/core.html#ID-637646024
Свенд,

35

Візьміть HTML і проаналізуйте структуру DOM. Потім візьміть структуру DOM і запишіть її назад у HTML. Під час запису сортуйте атрибути, використовуючи будь-яке стабільне сортування. Тепер ваш HTML буде нормалізований щодо атрибутів.

Це загальний спосіб нормалізації речей. (проаналізуйте ненормовані дані, а потім запишіть їх назад у нормалізованій формі).

Я не впевнений, чому ви хочете нормалізувати HTML, але там у вас є. Дані - це дані. ;-)


1
У вас є приклад коду. Я намагався зробити щось подібне, це не спрацювало.
Жюльєн

12

Це доказ концепції, його, безумовно, можна оптимізувати:

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, $ ('# різний'). Тепер $ ('# original'). Html () і $ ('# different'). Html () показують HTML-код з атрибутами в однаковому порядку.


Я думаю, краще, якщо ви згенеруєте вміст html у XML, а потім відтворите його за допомогою xslt. Ви напевно отримаєте приємніший результат.
Насаралла

8

Ви можете спробувати відкрити вкладку HTML у firebug, атрибути завжди в однаковому порядку


4
Це не дуже корисно само по собі. Це тому, що він заново створює HTML із DOM, але, проте, це має певний порядок ітерацій атрибутів (або Firebug сортує їх вручну). Жюльєн міг скористатися цим і використати той самий метод для випису HTML.
Метт Кантор,

5

Насправді я можу придумати кілька вагомих причин. Можна порівняти порівняння ідентичності та використання з інструментами типу „diff”, де досить прикро, що семантично еквівалентні рядки можуть бути позначені як „різні”.

Справжнє запитання - "Чому в Javascript"?

Це питання "пахне" "у мене проблема, і я думаю, що маю відповідь ... але у мене є проблема і зі своєю відповіддю".

Якщо ОП пояснить, чому вони хочуть це зробити, їх шанси отримати хорошу відповідь різко зростуть.


2

Питання "Що для цього потрібно?" Відповідь: Це робить код більш читабельним та легшим для розуміння.

Чому більшість інтерфейсів відмовляє ... Багато програмістів не розуміють необхідності спрощення роботи користувачів. У цьому випадку робота користувачів - це читання та розуміння коду. Однією з причин замовлення атрибутів є людина, яка повинна налагоджувати та підтримувати код. Впорядкований список, з яким програма знайомиться, полегшує йому роботу. Він може швидше знаходити атрибути або розуміти, яких атрибутів не вистачає, і швидше змінювати значення атрибутів.


Думає, що ви недостатньо довго думали над цим питанням; навіть діюче вирішення питання не стосуватиметься того, що ви тут говорите, хоч це і правда.
issa marie tseng

Чому ви вважаєте, що ОП хоче зробити це за допомогою Javascript? Це можливо , що на стороні сервера (час збирання?) Javascript рішення було на увазі, але це малоймовірно , що хтось - то досить досвідчений , щоб зробити це не вдалося б згадати про це в пості StackOverflow. Також можливо, що OP реалізує HTML-редактор у браузері, але це також видається сумнівним.
Пойнті

0

Це має значення лише тоді, коли хтось читає джерело, тому для мене це семантичні атрибути спочатку, менш семантичні атрибути далі ...

Звичайно, є винятки. Якщо у вас є, наприклад, послідовні <li>, усі з одним атрибутом на кожному, а інші лише на деяких, можливо, ви хочете переконатися, що всі спільні знаходяться на початку, а потім окремі, наприклад .

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

(Навіть якщо атрибут "b" більш семантично корисний, ніж "a")

Ви зрозуміли ідею.


0

я думаю, це насправді можливо, якщо вміст html передається як xml і відображається через xslt ... тому ваш вихідний вміст у XML може бути в будь-якому порядку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.