JavaScript - DOM: свойства textContent, innerHTML и др.

Александр Мальцев
103K
1

На этом уроке мы рассмотрим свойства, предназначенные для работы с текстовым содержимым элемента (textContent, innerText, outerText) и свойства, предназначенные для работы с HTML содержимым элемента (innerHTML, outerHTML).

Свойство textContent и как оно работает

textContent – это свойство, которое предназначено для работы с текстовым контентом элемента. Оно позволяет его как получить (включая текстовое содержимое всего его потомков), так и установить.

Синтаксис:

// $elem – некоторый DOM-элемент

// получим текстовый контент $elem
const text = $elem.textContent;
// установим текстовый контент $elem:
$elem.textContent = 'Некоторый текст...';

Примеры с textContent

1. При получении текста элемента, содержащего один текстовый узел, textContent возвратит текст, находящийся внутри этого текстового узла.

Пример:

Как в JavaScript получить текстовое содержимое элемента, содержащего один текстовый узел
<p id="some-paragraph">Некоторый текст</p>

<script>
  const $elem = document.querySelector('#some-paragraph');
  const text = $elem.textContent; // "Некоторый текст"
</script>

2. Для элемента, который содержит множество других узлов, textContent вернёт конкатенацию (сложение) текстов всех его текстовых узлов.

Пример:

Использование textContent для получения текстового контента элемента, содержащего множество других узлов
<div id="message">Внимание! <span>Это <strong>очень важный текст.</strong></span><script>alert('А это очень важное сообщение!');</script></div>

<script>
  const $elem = document.querySelector('#message');
  const text = $elem.textContent; // "Внимание! Это очень важный текст.alert('А это очень важное сообщение!');"
</script>

В этом примере текстовые узлы обозначены цифрами. textContent вернёт сложение текстов этих текстовых узлов.

3. При получении textContent у document, оно возвратит null:

const text = document.textContent; // null

При установке элементу текстового содержимого, textContent удалит всего его узлы (при их наличии), и добавит в него один текстовый узел, содержащий указанный текст.

4. Например, установим элементу #message новое текстовое содержимое:

<!-- HTML -->
<div id="message">Внимание! <p>Это <strong>очень важный текст.</strong></p><script>alert('А это очень важное сообщение!');</script></div>

<script>
  const $elem = document.querySelector('#message');
  // эта строчка удалит все элементы в #message и добавит в него текстовый узел с текстом "Новый текст..."
  $elem.textContent = 'Новый текст...';
</script>

После установки $elem текстового контента, он будет выглядеть следующим образом:

JavaScript - Установка элементу текстового содержимого с помощью свойства textContent

5. Например, создадим элемент «div.alert», вставим в него некоторый текст и добавим его на страницу перед закрывающим тегом body:

// создадим элемент <div></div>
const $alert = document.createElement('div');
// добавим к $alert класс alert
$alert.className = 'alert';
// установим $alert текстовый контент
$alert.textContent = 'Некоторый текст...';
// вставим на страницу перед </body>
document.body.appendChild($alert);

6. Если присвоить textContent строку, содержащую HTML код, то символы < и > будут заменены соответственно на &lt; и &gt;.

$elem.textContent = '<p>...</p>';
const text = $elem.textContent; // "&lt;p&gt;...&lt;/p&gt;"

innerText, outerText и их отличие от textContent

innerText также как textContent используется для извлечения текста из элементов.

Но innerText в отличие от textContent как бы копирует текст, отображаемый этим элементом в браузере. Он учитывает стили, применённые к элементу (отображается элемент или нет). Когда элемент скрыт, innerText не включает его текстовый контент в возвращаемые данные.

Кроме этого, innerText не добавляет в возвращаемый результат содержимое style и script.

При установке элементу текстового контента, innerText также как textContent удаляет все имеющиеся в нём узлы и создаёт новый текстовый узел с указанным содержимым.

Синтаксис свойства innerText:

// получим текстовый контент $elem
const text = $elem.innerText;
// зададим $elem текстовый контент
$elem.innerText = 'Новый текст...';

Пример, в котором показана разница между innerText и textContent:

<div id="message">Внимание! <span>Это <strong>очень важный текст.</strong></span><script>alert('А это очень важное сообщение!');</script></div>

<script>
  const $elem = document.querySelector('#message');
  const textByTextContent = $elem.textContent; // "Внимание! Это очень важный текст.alert('А это очень важное сообщение!');"
  const textByInnerText = $elem.innerText; // "Внимание! Это очень важный текст."
</script>

Из примера видно, что innerText не включает в возвращаемые данные контент элемента script.

В этом примере мы ещё дополнительно удалим отображение элемента span из документа, т.е. установим ему «display: none»:

<style>
/* CSS */
#message > span {
  display: none;
}
</style>

<div id="message">Внимание! <span>Это <strong>очень важный текст.</strong></span><script>alert('А это очень важное сообщение!');</script></div>

<script>
  const $elem = document.querySelector('#message');
  const textByTextContent = $elem.textContent; // "Внимание! Это очень важный текст.alert('А это очень важное сообщение!');"
  const textByInnerText = $elem.innerText; // "Внимание!"
</script>

Таким образом innerText учитывает стили элементов, и возвращает только текст отображаемый этим элементом в браузере.

Использование JavaScript свойства innerText для получения текстового контента элемента

outerText

Ещё в DOM API у элементов имеется свойство outerText. Оно возвращает текстовое содержимое элемента аналогично свойству innerText.

Синтаксис свойства outerText:

// получим текстовый контент $elem
const text = $elem.outerText;
// установим $elem текстовый контент
$elem.outerText = 'Текстовый контент...';

Его отличие от innerText только в том, что outerText при установки элементу текстового контента удаляет не только всё его содержимое, но и сам этот элемент и помещает на этом месте новый текстовый узел с заданным текстом.

Например, заменим все элементы img на текст 'Здесь было изображение':

<div class="container">
  <div>...</div>
  <img src="image-01.png" alt="...">
  <div>...</div>
  <img src="image-02.png" alt="...">
</div>

<script>
  // получим все элементы с тегом img
  const $elem = document.querySelectorAll('img');
  // переберём все найденные элементы
  $elem.forEach(($item) => {
    // заменим элемент на текст
    $item.outerText = 'Здесь было изображение';
  });
</script>

innerHTML и outerHTML

innerHTML предназначен для установки или получения HTML разметки элемента.

Синтаксис:

// получим HTML содержимое $elem
const html = $elem.innerHTML;
// установим $elem новый HTML
$elem.innerHTML = '<div>...<div>';

Например, установим элементу ul#list новое HTML содержимое:

// получим HTML элемент ul по его id
const $elem = document.querySelector('#list');
// установим $elem новый HTML
$elem.innerHTML = `<li>HTML</li><li>CSS</li><li>JavaScript</li>`;

Пример, в котором получим HTML разметку некоторого элемента:

<div class="message">Я люблю <strong>JavaScript</strong>! Он позволяет <span>сделать что угодно со страницей</span>.</div>

<script>
// получим HTML элемент .message
const $elem = document.querySelector('.message');
// получим HTML код $elem
const html = $elem.innerHTML;
</script>

Задание HTML содержимого элементу с помощью innerHTML всегда сопровождается удалением его контента и установкой ему новой HTML разметки, но основе указанной строки, которая была разобрана внутренним парсером браузера как HTML.

Начинающие веб-разработчики при написании такого кода полагают что он добавит только указанную HTML разметку в конец содержимого $someElem:

$someElem.innerHTML += '<div>...</div>';

Но на самом деле это не так. Этот код выполняет следующее:

  1. получает текущее содержимое $someElem, т.е. HTML-строку, к которой прибавляет ещё одну строку <div>...</div>;
  2. очищает всё что есть в $someElem;
  3. устанавливает $someElem HTML, полученный в результате разбора результирующей строки.

Эквивалентная запись кода, приведённого выше:

let html = $someElem.innerHTML;
html = html + '<div>...</div>';
$someElem.innerHTML = html;

Таким образом, используя такую запись мы не просто добавляем некоторый HTML в конец элемента, а полностью переустанавливаем его. Выполнение такого кода обычно сопровождается «миганием».

Поэтому, в ситуациях, когда вам нужно просто добавить некоторый фрагмент HTML разметки в некоторый элемент лучше воспользоваться, например, методом insertAdjacentHTML.

Пример использования innerHTML для очистки содержимого элемента:

$elem.innerHTML = '';

Например, получить и изменить HTML контент элемента р с id="myP":

var myP = document.getElementById("myP");
//получить HTML содержимое элемента, имеющего id="myP"
myP.innerHTML;
//изменить HTML содержимое элемента, имеющего id="myP"
myP.innerHTML = "<em>Что-то новое</em>";

Например, удалить HTML контент элемента p, имеющего id="demo":

document.getElementById("demo").innerHTML = "";
Javascript - свойства innerHTML и outerHTML Javascript - работа со свойствами innerHTML и outerHTML

outerHTML

Свойство outerHTML устанавливает или возвращает HTML контент, представляющий сам элемент и его дочерние элементы.

Например, получить и изменить HTML контент списка ul, имеющего id="myList":

var myList = document.getElementById("myList");
//получить HTML список
myList.outerHTML;
//заменить HTML список на новый
myList.outerHTML = "<ul><li>HTML</li><li>CSS</li><li>JavaScript</li></ul>";

Задания

  1. Напишите сценарий, который изменит содержимое всех элементов p в документе.
  2. Напишите сценарий, который заменит HTML содержимое элемента body на другое. Условием для запуска сценария является время, равное 5 секундам, которое прошло с момента полной загрузки страницы.

Комментарии ()

  1. Esgard
    Вчера в 13:43
    Добрый день!
    Нужна помощь в написании скрипта, который будет заменять наименование ссылки в меню сайта.
    Суть в чем: на сайте пункт меню назван «Тренинги», поставили задачу сделать так, чтобы вместо «Тренинги» было «Курсы».
    var div = document.createElement('.gc-account-user-submenu .menu-item-trainings .subitem-link');
    div.innerHTML = "Курсы";
    
    Но скрипт не сработал. правильно ли написан?
    1. Александр Мальцев
      3 минуты назад
      Привет! Если нужно изменить контент у уже имеющегося на странице элемента, то так:
      let div = document.querySelector('.gc-account-user-submenu .menu-item-trainings .subitem-link');
      div.textContent = 'Курсы';
      
      Метод createElement предназначен для создания элементов.
    2. Дмитрий
      03 июня 2020, 14:13
      Подскажите пожалуйста )!
      Очень нужна помощь в написании короткого кода (js)
      Есть кнопка фиксированная на странице, нужно менять текст в зависимости от блока data-section-title="?" при скроле страницы

      
      <div class="main_page_box_fix_mobile_btn">
      	<a href="#!" class="main_page_btn main_page_btn_orange main_page_btn_normall">Напиши нам!</a>
      </div>
      
      <section data-section-title="lorem ?">
      </section>
      
      <section data-section-title="lorem ?">
      </section>
      
      <section data-section-title="lorem ?">
      </section>
      
      
      1. Александр Мальцев
        03 июня 2020, 14:46
        Этот вопрос не относится к этой теме.
        Скрипт на jQuery для решения этой задачи будет такой:
        <script>
          var dataSectionTitles = $('section[data-section-title]');
          $(window).scroll(function () {
            var fromTop = $(this).scrollTop();
            var index = -1;
            for (var i = dataSectionTitles.length - 1; i >= 0; i--) {
              if ($(dataSectionTitles[i]).offset().top - 200 < fromTop) {
                index = i;
                break;
              }
            }
            if (index !== -1) {
              $('.main_page_btn').text(dataSectionTitles.eq(i).attr('data-section-title'));
            }
          });
          $(window).scroll();
        </script>
        
        1. Дмитрий
          03 июня 2020, 14:52
          Проблема в том что у меня в проекте нет JQ, и нужно на чистом JS(((
          Поможете?
      2. Иван
        08 октября 2016, 09:06
        Здравствуйте! Вывел отдельные блоки из index.html в отдельный script.js
        НО блоки 2 одновременно не выводятся на экран. Что-то напутал скорее всего в синтаксисе JS

        
        
        $(document).ready(function() {
        	
        
        	var waypointsvg = new Waypoint({
        
        		element: $(".section_5"),
        		handler: function(dir) {
        			
        			if (dir === "down") {
        
        				$(".section_5 .tc-item").each(function(index) {
        					var ths = $(this);
        					setTimeout(function() {
        						var myAnimation = new DrawFillSVG({
        							elementId: "tc-svg-" + index
        						});
        						ths.children(".tc-content").addClass("tc-content-on");
        					}, 500*index);
        				});
        
        			};
        			this.destroy();
        		},
        		offset: '35%'
        	});
        });
            
        var s="<p>Здесь расположен текст, вынесенный в JS</p>";
        document.getElementById("js-123").innerHTML=s;
        
        var m="<img src='img/fire.png' class='img-responsive' alt='BlaBla'>";
        document.getElementById("js-456").innerHTML=m;
        
        

        В index. html:

        
        <span id="js-456"><span>
        <span id="js-123"><span>
        
        
        
        1. Александр Мальцев
          10 октября 2016, 11:38
          Здравствуйте, у Вас элементы span не закрыты:
            <span id="js-456"></span>
            <span id="js-123"></span>
          
        Войдите, пожайлуста, в аккаунт, чтобы оставить комментарий.