Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > outerHTML|innerHTML != actual HTML


Автор: JSman 23.7.2008, 17:09
Меня интересует только ИЕ. 

Проблема в том, что мне нужно получить именно фактический или хотя бы вылидный код страницы средствами JavaScript.
Итак, этому мешают:
1) у значений атрибутов, состоящих из одного "слова", пропадают кавычки
2) даже при валидном html коде пропадают закрывающие теги некоторых элементов,  например DD, DT.

Первая проблема лечится регулярным выражением.
Вторая до конца не выяснена. Может быть кто-нибудь знает список закрывающихся тегов, которые удаляются при использовании outerHTML и innerHTML?

outerHTML, innerHTML отображают тот код, который браузер отпарсил и хранит в себе. Поэтому обходы через textRange никак не помогут.

Добавлено через 2 минуты и 6 секунд
Ajax не предлагать. Интересует код странички в динамическом состоянии.

Автор: SelenIT 24.7.2008, 02:17
Уже давно есть скрипты, преобразующие подобную бяку в XHTML после WYSIWYG-ов, напр. http://html2xhtml.richarea.com/. Насколько помню, оно основано на регулярках, вроде как проверено временем.

Насчет общих правил (кого оно закрывает, а кого нет, и т.п.) сильно сомневаюсь. По-моему, эти правила меняются от версии к версии (напр., IE5 не закрывал LI, кроме последнего в списке, IE6 уже закрывает). Порядок атрибутов в этом коде у разных версий тоже разный.


В порядке альтернативы можно было бы вообще отказаться от innerHTML и сериализовать DOM своими силами (рекурсивно обходя коллекции детей каждого элемента и их коллекции атрибутов) - будет гарантированно по тем правилам, какие нужно, но ооочееень мееедлеееннооо...

Автор: JSman 24.7.2008, 10:51
SelenIT, спасибо! 

Время надо померить обязательно 

Код

//$.js

$timeArray = [];

$time = function (commentString)
{    
    if (commentString) window.$timeArray.push(commentString);
    window.$timeArray.push(new Date());

}

$timeResult = function ()
{
    var d = new Date;
    for (var i=0; i<$timeArray.length; i++)
    if ($timeArray[i] instanceof Date) $timeArray[i] = d - $timeArray[i];
    
    return $timeArray;
}

$timeEmpty = function ()
{
    window.$timeArray = [];    
}


ставим $time(), где хотим поставить отметку
аргумент к $time() - это комментарий

результаты содержатся в $timeArray


Что я нашел быстрое, напишу сюда (хотя все равно исправлять все придется там). А если присоединитесь к поиску решения проблемы, то замечательно будет)

Автор: JSman 24.7.2008, 11:56
http://html2xhtml.richarea.com/ - есть реальные ошибки интерпретации.

беру для проверки этот документ
http://www.w3.org/TR/2001/CR-css3-selectors-20011113/

Автор: JSman 24.7.2008, 12:48
Код

code = code.replace(/<(?:area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param)[^>]*/ig,'$& /'); //fix empty elements
code = code.replace(/(=)([^ >"']+)/ig,'$1"$2"'); //attribute quoters fix


теперь остается добавить закрывающие теги к блочным элементам...

Автор: Sardar 24.7.2008, 14:47
Если doctype прописать и убедиться что браузер в Standards Compliant mode, то по идее браузер валидный код выдавать должен. Старых IE нет, проверить не могу.

Автор: JSman 25.7.2008, 12:52
IE6/7 при 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

javascript:alert(document.compatMode) выдает CSS1Compat, но при этом проблема не решается, в отличии от Оперы, например.

Итак, тогда остаются регулярные или серверный компонент писать и связываться по аяксу.

Sardar, у тебя другие результаты по стандартам?

Автор: SelenIT 25.7.2008, 18:23
Цитата(JSman @  23.7.2008,  17:09 Найти цитируемый пост)
даже при валидном html коде пропадают закрывающие теги некоторых элементов,  например DD, DT.

В HTML это http://www.w3.org/TR/html401/index/elements.html (закрывающий тег для них помечен как опциональный) и не нарушает валидности. А XHTML IE любых версий, к сожалению, просто не знает...

Автор: JSman 26.7.2008, 17:09
Цитата(SelenIT @  25.7.2008,  18:23 Найти цитируемый пост)
А XHTML IE любых версий, к сожалению, просто не знает

Действительно, зашел на msdn и увидел потрясающий блог о том, что поддержка xhtml, <?xml> для версий 6 и 7 была специально не реализована. Объясняется это тем, что в подключение DTD с других доменов угрожает безопасности.

При всем этом, получение валидного xhtml кода из html возможно с нормальной скоростью конвертирования и на JavaScript.

Вот полный список, обнаруженных мною, проблем, связанных с конвертированием:
1. optionalEndingTags = /body|colgroup|dd|dt|head|html|li|option|p|tbody|td|tfoot|th|thead|tr/ - обращаем на них внимание
2. обязательное присутствие tbody в табличках
3. attributes = /noshade|checked|selected|multiple|nowrap|disabled/
4. li, кроме последнего, не закрываются в любом случае
5. кавычки значений атрибутов

Самое лучшее, что я могу предложить это:
1. Создавать валидный xhtml код - это позволит отобразить большинство закрывающих необязательных тегов
2. Обязательно включать в таблицы тег tbody
3. Кавычки исправить code = code.replace(/(=)([^ "'>]+)/ig,'$1"$2"');
4. code = code.replace(/(<[^>]+)(noshade|checked|selected|multiple|nowrap|disabled)([^=])/ig, '$1$2="$2"$3');
5. code = code.replace(/<(?:area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param)[^>]*/ig,'$& /')
6. закрыть, опять же регулярными выражениями, теги li.

Таким образом, 4х регулярных выражений вполне достаточно для решения этой задачи.

Если есть дополнения, буду рад замечаниям.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)