215 читателей, 57 постов
Администрация
Модераторы
Блог создан для обсуждения браузера Microsoft Internet Explorer, в том числе особенностей написания для него веб-страниц.
innerHTML
, которое получает строку, делает синтаксический анализ HTML и заменяет его содержимое новым HTML. В данном случае я пытался заменить содержимое TBODY новым набором рядов:<table> <tbody id="rows"> <tr>.... <tr>.... ... </tbody> </table> var tb = document.getElementsByName('rows')[0]; tb.innerHTML = "<tr>......";
innerHTML
, но затем вспомнил, что именно я ответственен за это ограничение! Как много разработчиков имеют потом дело с последствиями их решений о продукте? Возможно, немногие. Давайте, я расскажу, как это было.innerHTML
, а также innerText
, outerHTML
, outerText
и менее известных методов insertAdjacentHTML
и insertAdjacentText
. Эти методы получают HTML или чистый текст и заменяют или вставляют новое содержимое в документ.innerHTML
, строка, содержащая HTML, проходит через синтаксический анализатор. Анализаторы HTML не столь просты как прямые анализаторы вроде XML. Синтаксический анализатор HTML (блестяще сделанный Дэвидом Бау) получает произвольный текст и, как правило, производит дерево элементов HTML. Например, в результате анализа файла, содержащего только «Foo», в будет дерево:<HTML><HEAD></HEAD> <BODY>Foo</BODY></HTML>
outerHTML
):Foo<script>alert(document.body.parentNode.outerHTML)</script>
<tr><td>Foo
» без тэга TABLE перед TR приводит к тому, что анализатор полностью игнорирует тэг TR. Может быть, это сделано в анализаторе IE для обратной совместимости с браузером того времени Netscape. Фактически, обратная совместимость влияет на большую часть сложности синтаксического анализатора.innerHTML
у TBODY равным «<tr>...
» приведёт к тому, что содержимое TBODY будет «Foo». Это страшно не «корректный» (англ. «valid») HTML, который можно было бы отобразить. Для того чтобы TR был создан, нужно предварить его тэгом TABLE. Попытка установить содержимое TBODY равным «<table><tr>...
», однако, имеет ещё меньший смысл, потому что вставка TABLE прямо в TBODY столь же бестолкова.<tr>...
», «контекстный синтаксический анализатор HTML» будет знать, что можно создать TR, так как его непосредственным родителем гарантировано будет TBODY, который может содержать TR.innerHTML
и других методов для попыток её изменений.innerHTML
у TBODY устанавливался во что-то, начинающееся с «<tr>
». В таком случае я мог присоединить в начале строки «<table>
» и затем выдернуть все TR из конечного дерева и заменить ими содержимое TBODY.<!-- новые строки --><tr>...
». Довольно скоро вы начнёте делать всю работу, которую настоящий синтаксический анализатор должен выполнять сам.innerHTML
. Было бы в удовольствие доработать синтаксический анализатор для работы с нетекстовым контекстом!visibility
, установленным в hidden
. Когда надо заменить ряды, я устанавливаю innerHTML
этого тэга равным чему-то вроде «<table><tbody><tr>...
». Так как элемент невидим, это не приводит к перерисовке страницы. Затем я использую метод DOM replaceChild
элементов для удаления старого TBODY и заменой его полученным. В результате таблица правильно изменяется и перерисовывается!<table> <tbody id="tb"> <tr>.... <tr>.... ... </tbody> </table> <span id=temp style='visibility:hidden'></span> var temp = document.getElementsByName('temp')[0]; temp.innerHTML = '<table><tbody><tr><td>New Row'; var tb = document.getElementsByName('tb')[0]; tb.parentNode.replaceChild(temp.firstChild.firstChild, tb);
комментарии (83)
Перевод компьютерный? Просто в процессе чтения, я немного сбиваюсь, т.к. не могу понять смысл некоторых фраз. Было бы неплохо увидеть человеческий перевод, или хотя бы адаптацию данного под человека
Это человеческий перевод, выполнен лично мною. Если есть претензии, то они, скорее всего, к автору.
вот тут, мне кажется, надо убрать «была». Я не придираюсь, просто это слово сбивает))
Вторая мысль: вот индусы!
Ну и судя по вашему посту, в Майкрософт за багфиксы денег не платят.
Не помню даже какой имелся в виду бразуер. В IE точно частенько возникают проблемы. Когда прижатый к низу футер вдруг оказывается не внизу. Решение: обрамлять каждый ряд флоатов.
Очень легко убедится, зайдите на сайт inthecity.ru браузером (FF, Opera, Chrome), а потом зайдите IE (6/7). Разница очевидна.
Блин… Ну почему, почему им тогда не дальше больше времени? Это решение настолько затормозило развитие целой индустрии под названием rich web applications…
Однако, все равно спасибо за статью.
Особенно вот это
>>Это не ужасно «правильный» или HTML, что можно отобразить.
Это звучит по-английски. Но по-русски режет глаз.
Возможный перевод
«Это не самый валидный код, да и отобразить его невозможно»
В русском языке вот так:
>>Попытка установить содержимое TBODY равным «...», однако,
Однако, попытка установить содержимое TBODY равным «...»
Вот тут вообще ничего не было ясно. Да и переведено неверно
>>Поэтому если где, в ответвлении тэгов присутствуют (от самого вложенного) TBODY, TABLE, BODY, HTML
Оригинал
>Thus, if the branch of tags were (from the bottom) TBODY, TABLE, BODY, HTML
Надо было перевести как
Поэтому, если ветка тегов (в обратном порядке) представляет из себя TBODY, TABLE, BODY, HTML
>>для реализации такой функциональности
такого функционала
>>Альтернативой всему этому было бы что-то «подделать»
Альтернативой было бы «подделать» что-нибудь
Работа переводчика нелегкая :)
> Особенно вот это
>>>Это не ужасно «правильный» или HTML, что можно отобразить.
> Это звучит по-английски. Но по-русски режет глаз.
> Возможный перевод
> «Это не самый валидный код, да и отобразить его невозможно»
Это жаргонизм и, вообще говоря, не по-русски. В качественном переводе такого быть не должно.
> В русском языке вот так:
>>>Попытка установить содержимое TBODY равным «...», однако,
> Однако, попытка установить содержимое TBODY равным «...»
Это как раз по-английски. По-русски будет вариант, использованный мной. Это не я придумал, это нас так учила в институте очень крутая преподавательница.
> Вот тут вообще ничего не было ясно. Да и переведено неверно
> >>Поэтому если где, в ответвлении тэгов присутствуют (от самого вложенного) TBODY, TABLE, BODY, HTML
> Оригинал
> >Thus, if the branch of tags were (from the bottom) TBODY, TABLE, BODY, HTML
> Надо было перевести как
> Поэтому, если ветка тегов (в обратном порядке) представляет из себя TBODY, TABLE, BODY, HTML
Бывает со мной, запятою промахнулся. Исправил.
> >>для реализации такой функциональности
> такого функционала
Спорно. Мне кажется, «функциональности» звучит лучше.
> >>Альтернативой всему этому было бы что-то «подделать»
> Альтернативой было бы «подделать» что-нибудь
Согласен, пропустил. Исправлено.
Замените на правильный.
>>Это не я придумал, это нас так учила в институте очень крутая преподавательница.
Порадовали :))
«Однако» в конце предложений (в том числе простых предложений в сложном) и не по теме в середине предложений ставят только представители одной национальности, однако.
Ваша учительница была не той национальности, однако? :)
Простите. Это шутка, конечно. Но в каждой шутке…
>>«функциональности» звучит лучше.
Функциональность в русском является суб-термином usability.
Функциональное устройство == удобное устройство
Нефункциональное == неудобное
— В любом случае мое дело предложить правки. Ваше дело отказаться.
Однако, с таким упорством не по делу вам будет трудно на Хабре (да и судя по описанию в профиле, вам уже нелегко).
Заменил всё предложение на «Это страшно не „корректный“ HTML, который можно было бы отобразить.»
> «Однако» в конце предложений (в том числе простых предложений в сложном) и не по теме в середине предложений ставят только представители одной национальности, однако.
Не знал. Это какой? А вообще, сложное предложение и простое, это, на мой взгляд, разные случаи. И в конец простого предложения я «однако» не ставлю :).
> Функциональность в русском является суб-термином usability.
> Функциональное устройство == удобное устройство
> Нефункциональное == неудобное
С чего вы это взяли? Можно легко привести много примеров функциональных, но неудобных в некоторых отношениях или даже полностью вещей. Например, ноутбук, с которого, я пишу функционален, но гулять с ним, нося до 3 кг веса не очень-то удобно. Или официальный клиент ICQ функционален, но очень многим не нравится именно по причине неудобства.
С другой стороны, можно привести пример малофункциональных, но довольно удобных вещей. Например, кровать может быть малофункциональной: на ней можно только спать, но зато это очень удобно.
А моё «упорство» заключается лишь в продуманности и обоснованности многих моих мнений. И менять мнение по первому веянию, если это необосновано, мне не с руки.
Удачи!
> установленным в hidden. Так как элемент невидим, это не приводит к перерисовке страницы.
Я всегда это знал. Разработчики экплорера индусы, не знают технологий, под которые пишут браузер. visibility: hidden элементы невидимы, но их изменение ПРИВОДТ к перерисовке страницы.
должен пропасть блок «вы можете использовать хтмл теги»
фсе ф шоке. как можно говорить о веб девелопменте на сайте, где нифига не по феншую все?
Не пойму я этого.
var tb = document.getElementById('rows');
там же
а вообще, я полностью согласен с тем что у table не должно быть innerHTML потому как есть методы insertRow и insertCell они вполне компенсируют это!
ps: считаю innerHTML ламерским подходом (хотя сам его часто использую=)) потому как если используете ДОМ, будьте любезны, используйте его в полной мере!
а вообще, я полностью согласен с тем что у table не должно быть innerHTML потому как есть методы insertRow и insertCell они вполне компенсируют это!
ps: считаю innerHTML ламерским подходом (хотя сам его часто использую=)) потому как если используете ДОМ, будьте любезны, используйте его в полной мере!
Они это почувствовали ;)
а вообще, я полностью согласен с тем что у table не должно быть innerHTML потому как есть методы insertRow и insertCell они вполне компенсируют это!
ps: считаю innerHTML ламерским подходом (хотя сам его часто использую=)) потому как если используете ДОМ, будьте любезны, используйте его в полной мере!
Если приложению нужна скорость, то innerHTML может ее дать. Совсем другой вопрос, что если вашему приложению совсем никуда без innerHTML, то велика вероятность что оно плохо спроектировано или как минимум имеет архитектурные изъяны.
а вообще ОО подход гибче, так как если надо будет с созданной структурой поработать подольше, то у Вас будут готовые обьекты, которые можно элементарно кэшировать, изменять (не ища по айди среди документа) напрямую итд.
2 Вы хоть раз создавали табличку клиенту на 2500 ячеек из приходящих данных? (это насчет тормознутого вывода)
кстати в том тесте можно увеличить скорость дома процентов на 30 если * засовывать как innerHTML а не как обьект, потому как это текст, в отличии от ячейки или ряда
2. Всю таблицу можно и при помощи innerHTML сделать. И всё равно это будет быстрее, чем через DOM и особенно через методы таблиц.
Не понял вашу фразу про тест. Он же сравнивает разные методы.
про тест: все методы полезны, и innerHTML тоже, но его не надо пичкать везде, и вставка таблицы через innerHTML это неправильный подход помоему
extjs.com/ — XTemplate
var firstTr=$j("#tatgetTable tr:first");
var newTr=firstTr.clone();
newTr.insertBefore(firstTr);
function loadXMLString(txt)
{
txt = '' + txt + '';
try //Firefox, Mozilla, Opera, etc.
{
var xmlDoc = new DOMParser().parseFromString(txt,«text/xml»);
return(xmlDoc);
}
catch(e)
{
try //Internet Explorer
{
var xmlDoc = new ActiveXObject(«Microsoft.XMLDOM»);
xmlDoc.async = «false»;
xmlDoc.loadXML(txt);
return(xmlDoc);
}
catch(e) {alert(e.message)}
}
return(null);
}
function dom2html(domnode, htmlnode)
{
var child; for(var i=0; child=domnode.childNodes[i]; i++)
{
if (child.nodeType==1)
{
var temp = document.createElement(child.nodeName);
var attr; for(var j=0; attr=child.attributes[j]; j++)
{
temp.setAttribute(attr.name, attr.value);
// newatt=document.createAttribute(attr.name);
// newatt.nodeValue=attr.value;
// temp.setAttributeNode(newatt);
}
htmlnode.appendChild(temp);
if (child.hasChildNodes()) {dom2html(child, temp);}
} else
if (child.nodeType==3)
{
var temp = document.createTextNode(child.nodeValue);
htmlnode.appendChild(temp);
} else
{
// alert(child.data);
//var temp = document.createCDATASection('');
//var temp = document.createElement(child.data);
//var temp = document.createCDATASection(child.data);
//htmlnode.appendChild(temp);
}
}
}
Пользоваться этим кодом следует так:
var dom = loadXMLString(arrhtml[id]).documentElement;
while (element.firstChild) element.removeChild(element.firstChild);
dom2html(dom, element);
1 строчка создает DOM из строки с HTML разметкой.
2 строчка чистит все внутри element
3 строчка вставляет DOM внутрь element
Хорошо хоть сейчас появилось объяснение этой проблемы.
Спасибо за перевод.
В IE оно не вставляется, только если заново создавать весь селект.
За наводку на решение проблемы спасибо.
P.S. insertAdjacentHTML воистину не недооцененный метод, его кстати легко эмулировать в браузерах его не имеющих