Полной загадкой для меня была эта абра-кадабра – “innerText | outerText | innerHTML | outerHTML” – решил в ней разобраться. Как бы ничего сложного, но нюансы, нюансы, которые и показывают, что на самом деле не понимаешь тему, а только думаешь, что понимаешь.
Часто для парсинга HTML страниц требуется вытащить что-нибудь этакое! И тут как всегда вариации – что использовать outerHTML или outerText, скажем, и в чем между ними разница? Итак, начнем с простого.
Пусть, скажем, у нас есть такая HTML конструкция
1 2 3 |
<!DOCTYPE html> <div id="test"><div>Everytime <b>Jesus Loves</b></div></div> </html> |
Для начала напишем на javascript несколько alert команд, которые покажут нам как работают innerText | outerText | innerHTML | outerHTML в браузерах.
1 2 3 4 5 6 7 8 9 10 11 12 |
<!DOCTYPE html> <div id="test"><div>Everytime <b>Jesus Loves</b></div></div> <script> alert("InnerText is: " + test.innerText); alert("OuterText is: " + test.outerText); alert("InnerHTML is: " + test.innerHTML); alert("OuterHTML is: " + test.outerHTML); </script> </html> |
А далее наступает самое интересное – результат начинает зависеть от браузера!!! И не только…
То есть, для Internet Explorer все отрабатывает идеально, а вот для FF Chrome первые 2 alert показывают undefined, оказывается там нет понятий innerText и outerText. Вместо них используются другие функции, но об этом позже. Отработаем полностью в IE и потом вернемся к браузерной совместимости.
Проверяем в Internet Explorer
[ezcol_1half][/ezcol_1half] [ezcol_1half_end][/ezcol_1half_end]
[ezcol_1half][/ezcol_1half] [ezcol_1half_end][/ezcol_1half_end]
Проверяем в FF
Как работают innerText | outerText | innerHTML | outerHTML в InternetExplorer?
Почему опять же в IE? С одной стороны, потому что свойств innerText и outerText нет в FF, Chrome, возможно других браузерах. Во-вторых, потому что один из моих любимых инструментов программирования – Delphi RAD Studio. А парсинг страниц в Delphi осуществляется при помощи экземпляра Internet Explorer (TWebBrowser) и библиотеки MSHTML.
Как работает innerText?
Насколько видно из эксперимента выше, innerText выдергивает содержимое между тегами, то есть там может быть сколь угодно много уровней вложенности, в нашем случае 3 уровня – div div b – то есть 3 уровня.
1 2 3 |
<!DOCTYPE html> <div id="test"><div>Everytime <b>Jesus Loves</b></div></div> </html> |
А получаем мы в итоге
Everytime Jesus Loves
То есть, innerText выдергивает с каждого уровня то, что находится между тегами и склеивает это в строку!
Как работает outerText?
Делает тоже самое, что и в innerText, но разница в том, что если мы проведем обратную операцию – присваивание, то outerText заменит все, включая теги, а innerText заменит только то, что между тегами.
Для наглядной демонстрации изменим немного код – добавим желтый фон, и сначала попробуем сделать присваивание элементу test.innerText
1 2 3 4 5 6 7 8 9 10 |
<!DOCTYPE html> <div style="background-color:yellow" id="test"><b>Jesus Loves</b></div> <script> alert('ChangingText'); test.innerText='New Changed text'; </script> </html> |
До
После
Желтая полоса осталась, потому что код поменялся таким образом
До применения innerText
1 |
<div style="background-color:yellow" id="test"><b>Jesus Loves</b></div> |
После применения innerText
1 |
<div style="background-color:yellow" id="test"><b>New Changed text</b></div> |
А если применить outerText, то желтая полоса исчезнет, потому что замена идет полностью, вместе с тегами.
1 2 3 4 5 6 7 8 9 10 11 12 |
<!DOCTYPE html> <div style="background-color:yellow" id="test"><b>New Changed text</b></div> <script> alert('ChangingText'); test.outerText='New Changed text'; </script> </html> |
Итак, разница теперь понятна.
До применения outerText
1 |
<div style="background-color:yellow" id="test"><b>Jesus Loves</b></div> |
После применения outerText
1 |
New Changed text |
Как работает innerHTML?
Здесь все достаточно тривиально – innerHTML берет все то, что заключено между тегами. Для первого примера выше результат будет выглядеть так…
1 |
<div>Everytime <b>Jesus Loves</b></div> |
Как работает outerHTML?
OuterHTML берет все целиком. То есть сами теги плюс то, что между тегами. Для первого примера выше результат будет выглядеть так…
1 |
<div id="test"><div>Everytime <b>Jesus Loves</b></div></div> |
Совместимость с другими браузерами
Если мы пишем на javascript для FF или Chrome, то innerText или outerText ими не поддерживаются! Есть определенные аналоги…
outerText иногда можно заменить конструкцией
1 |
obj.parentNode.innerHTML |
innerText можно условно заменить конструкцией
1 |
textContent |
Все во многом зависит от задачи!
Как работают innerText | outerText | innerHTML | outerHTML в Delphi?
Известно, что TWebbrowser использует IE при работе под Windows. Поэтому, в принципе функционал должен работать по аналогии. Проверим это!
Ниже коды 4 соответствующих кнопок…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
procedure TForm2.innerTextClick(Sender: TObject); var i:integer; Collection: IHTMLElementCollection; Element:IHTMLElement; begin //memo1.Lines.Clear; for i := 0 to idoc.all.length-1 do begin element:=idoc.all.item(i,0) as IHTMLElement; if element.id='test' then begin memo1.Lines.Add('innerText'); memo1.Lines.Add(element.innerText+#13#10); end; end; end; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
procedure TForm2.OuterTextClick(Sender: TObject); var i:integer; Collection: IHTMLElementCollection; Element:IHTMLElement; begin //memo1.Lines.Clear; for i := 0 to idoc.all.length-1 do begin element:=idoc.all.item(i,0) as IHTMLElement; if element.id='test' then begin memo1.Lines.Add('outerText'); memo1.Lines.Add(element.outerText+#13#10); end; end; end; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
procedure TForm2.innerHTMLClick(Sender: TObject); var i:integer; Collection: IHTMLElementCollection; Element:IHTMLElement; begin //memo1.Lines.Clear; for i := 0 to idoc.all.length-1 do begin element:=idoc.all.item(i,0) as IHTMLElement; if element.id='test' then begin memo1.Lines.Add('innerHTML'); memo1.Lines.Add(element.outerText+#13#10); end; end; end; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
procedure TForm2.OuterHTMLClick(Sender: TObject); var i:integer; Collection: IHTMLElementCollection; Element:IHTMLElement; begin //memo1.Lines.Clear; for i := 0 to idoc.all.length-1 do begin element:=idoc.all.item(i,0) as IHTMLElement; if element.id='test' then begin memo1.Lines.Add('outerHTML'); memo1.Lines.Add(element.outerHTML+#13#10); end; end; end; |