Как нормализовать 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»?

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

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


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 может быть в любом порядке.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.