5 причин избегать 'innerHTML’
при использовании JavaScript для изменения DOM
Вступление
Когда я писал базовый JS для манипуляций с DOM и прослушивания событий, я обнаружил ошибку, которая поставила меня в тупик. Я потратил время на изучение Stack Overflow в поисках решения, но безрезультатно. Чтобы воспроизвести ошибку, я представлю упрощенную версию своего кода.
Для начала у меня был простой HTML-файл с одним div
в теле:
В файле JavaScript я добавил несколько узлов в DOM и создал прослушиватель событий на кнопке:
В браузере моя страница появилась как положено. Есть изображение, за которым следует кнопка и дополнительный текст, который я добавил в DOM.
С первого взгляда на код у кнопки есть четко определенное назначение. При щелчке по нему на консоль должна выводиться строка hello
. Однако при нажатии кнопки ничего не печатается. Почему?
Во-первых, давайте попробуем выяснить, где в код вносится ошибка. Для начала закомментирую строку div.innerHTML +=
.
Теперь, когда я нажимаю кнопку, все работает как положено. После нажатия кнопки hello
регистрируется в консоли.
Очевидно, что строка с innerHTML +=
вызывает серьезные проблемы. Программисту JS кажется естественным использование таких операторов, как ++
и +=
. Однако использование оператора +=
с innerHTML
вызовет серьезные проблемы. Ниже мы обсудим, почему.
Добавление к 'innerHTML'
повторяет анализ всего тега
Когда вы используете оператор добавления с innerHTML
, Javascript повторно анализирует содержимое всего тега и воссоздает все элементы HTML.
'innerHTML'
очень медленно
Как естественный побочный эффект предыдущей причины, повторный анализ делает innerHTML
чрезвычайно медленным. Для небольшого HTML-документа со статическим текстом это может не быть проблемой. Однако для больших документов процесс повторного анализа занимает очень много времени и может иметь непредвиденные побочные эффекты.
'innerHTML’
Удаляет прослушиватели событий
Самый очевидный вывод из нашего краткого эксперимента: innerHTML
удаляет прослушиватели событий, которые ранее были добавлены в DOM. Поскольку весь тег (div
в нашем коде) повторно анализируется, прослушиватель событий теряется в процессе. Вместо использования оператора +=
используйте функции DOM, такие как append()
.
'innerHTML’
представляет угрозу безопасности
Использование innerHTML
создает потенциальную угрозу безопасности вашего веб-сайта. Злоумышленники могут использовать межсайтовые сценарии (XSS) для добавления вредоносных клиентских сценариев, которые крадут личную информацию пользователя, хранящуюся в файлах cookie сеанса.
Вы можете прочитать Документацию MDN на innerHTML
.
Совместимые с W3C методы позволяют легко добавлять новые элементы DOM
Такие методы, как .createElement()
, appendChild()
, append()
и removeChild()
, позволяют безопасно манипулировать DOM без непредвиденных последствий innerHTML
(и innerHTML+=
, в частности). Если вы просто не устанавливаете текст внутри тега HTML, например <p>
или <div>
, держитесь подальше от innerHTML
.
Для начинающих innerHTML
кажется самым простым и элегантным способом манипулировать базовыми элементами в DOM. Однако по мере того, как ваш JS становится более задействованным, а ваш DOM увеличивается в размере, innerHTML
ухудшает производительность и создает риски для безопасности.