Как нормализовать HTML в JavaScript или jQuery?

84

Теги могут иметь несколько атрибутов. Порядок, в котором атрибуты появляются в коде, не имеет значения. Например:

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

Как я могу «нормализовать» HTML в Javascript, чтобы порядок атрибутов всегда был одинаковым? Мне все равно, какой порядок будет выбран, главное, чтобы он всегда был одинаковым.

ОБНОВЛЕНИЕ : моей первоначальной целью было упростить сравнение (в JavaScript) двух 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
Зачем это нужно?
Рахул
40
@rahul: на самом деле в этом есть довольно интересная потребность: это может значительно улучшить сжатие gzip ваших страниц.
haylem
11
ах, в Javascript ... столько для сжатия. Не знаю, в чем тогда необходимость.
haylem
13
@Julien: К моменту запуска вашего кода JavaScript страница уже была отправлена ​​клиенту. Тогда я не понимаю, как это может помочь в сжатии.
Касабланка
22
На самом деле есть допустимое использование для попытки сделать то, что просит OP. Использование редактора WYSIWYG для управления вики. Проект, над которым я работаю, делает именно это, и редактор будет менять порядок атрибутов каждый раз, когда вы редактируете вики, что приводит к ненужным различиям. Я заканчиваю сортировку атрибутов в алфавитном порядке в представленном HTML на серверной части перед сохранением, чтобы избежать различий; так же легко можно было бы выполнить такую ​​сортировку в javascript перед отправкой.
Фрэнк Фармер,

Ответы:

68

На самом деле JavaScript не видит веб-страницу в виде текстового HTML, а скорее как древовидную структуру, известную как DOM или объектная модель документа. Порядок атрибутов элементов HTML в DOM не определен (на самом деле, как отмечает Svend, они даже не являются частью DOM), поэтому идея их сортировки в точке, где выполняется JavaScript, не имеет значения.

Я могу только догадываться, чего вы пытаетесь достичь. Если вы пытаетесь сделать это для повышения производительности JavaScript / страницы, большинство средств визуализации HTML-документов, по-видимому, уже приложили много усилий для оптимизации доступа к атрибутам, так что здесь мало что можно получить.

Если вы пытаетесь упорядочить атрибуты, чтобы сделать gzip-сжатие страниц более эффективным, когда они отправляются по сети, имейте в виду, что JavaScript запускается после этого момента времени. Вместо этого вы можете захотеть взглянуть на вещи, которые работают на стороне сервера, хотя, вероятно, это больше проблем, чем того стоит.

Тунг Нгуен
источник
8
JavaScript может работать на стороне сервера.
Мэтт Кантор,
Атрибуты не считаются частью дерева документа (которое естественно использует порядок). Таким образом, в то время как Attr наследует интерфейс узла, DOM Core 2 указывает, что эти поля имеют значение NULL для атрибутов w3.org/TR/DOM-Level-2-Core/core.html#ID-637646024
Svend
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, $ ('# different'). Теперь $ ('# original'). Html () и $ ('# different'). Html () показывают HTML-код с атрибутами в том же порядке.

Жюльен
источник
Я думаю, лучше, если вы создадите свое HTML-содержимое в XML, а затем отрендерите его с помощью xslt. Вы обязательно получите лучший результат.
Nasaralla 06
8

вы можете попробовать открыть вкладку HTML в firebug, атрибуты всегда в одном порядке

цурахман
источник
4
Само по себе это не очень полезно. Это потому, что он воссоздает HTML из DOM, и, однако, это происходит с определенным порядком итерации атрибутов (или Firebug сортирует их вручную). Жюльен мог бы воспользоваться этим и использовать тот же метод для написания HTML.
Мэтт Кантор,
5

На самом деле, я могу придумать несколько веских причин. Один из них - сравнение для сопоставления идентичности и для использования с инструментами типа 'diff', где довольно раздражает то, что семантически эквивалентные строки могут быть помечены как "разные".

Настоящий вопрос: «Почему именно в Javascript»?

Этот вопрос «пахнет» словами: «У меня есть проблема, и я думаю, что у меня есть ответ ... но у меня тоже есть проблема с моим ответом».

Если ОП объяснит, почему они хотят это сделать, их шансы получить хороший ответ резко возрастут.

Snowhare
источник
2

На вопрос "Зачем это нужно?" Ответ: Это делает код более читаемым и понятным.

Почему большинство UI - отстой ... Многие программисты не понимают необходимости упрощения работы пользователей. В этом случае работа пользователя - это чтение и понимание кода. Одна из причин заказать атрибуты для человека, который должен отлаживать и поддерживать код. Упорядоченный список, с которым знакомится программа, облегчает его работу. Он может быстрее находить атрибуты или понимать, какие атрибуты отсутствуют, и быстрее изменять значения атрибутов.

подписанный бит
источник
Мне кажется, вы недостаточно долго думали над этим вопросом; даже рабочее решение вопроса не будет соответствовать тому, что вы здесь говорите, хотя это может быть правдой.
issa marie tseng
Почему вы думаете, что OP захочет сделать это с помощью Javascript? Это возможно , что на стороне сервера (время сборки?) Javascript решение было в виду, но это маловероятно , что кто - то достаточно опытный , чтобы сделать это не удалось бы упомянуть об этом в посте StackOverflow. Также возможно, что OP реализует HTML-редактор в браузере, но это также кажется сомнительным.
Pointy
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 может быть в любом порядке.

Насаралла
источник