Почему document.write считается "плохой практикой"?

Я знаю document.write считается плохой практикой; и я надеюсь составить список причин, чтобы представить стороннему поставщику, почему они не должны использовать document.write в реализации их аналитического кода.

Пожалуйста, укажите причину претензии document.write как плохая практика ниже.

16 ответов

Решение

Несколько из более серьезных проблем:

  • document.write (далее DW) не работает в XHTML

  • DW напрямую не модифицирует DOM, предотвращая дальнейшие манипуляции (пытаясь найти доказательства этого, но в лучшем случае это ситуативно)

  • DW, выполненный после завершения загрузки страницы, перезапишет страницу или напишет новую страницу, или не будет работать

  • DW выполняется там, где встречается: он не может внедрить в заданной точке узла

  • DW эффективно пишет сериализованный текст, который концептуально не работает с DOM, и это простой способ создавать ошибки (.innerHTML имеет ту же проблему)

Намного лучше использовать безопасные и дружественные DOM методы манипулирования DOM

Там на самом деле ничего плохого document.write, как таковой. Проблема в том, что злоупотреблять им действительно легко. Грубо, даже.

С точки зрения поставщиков, предоставляющих аналитический код (например, Google Analytics), для них это самый простой способ распространения таких фрагментов.

  1. Это держит сценарии маленькими
  2. Им не нужно беспокоиться о переопределении уже установленных событий загрузки или включении необходимой абстракции для безопасного добавления событий загрузки
  3. Это очень совместимо

Пока вы не пытаетесь использовать его после загрузки документа, document.write по моему скромному мнению, это не зло.

Еще одно законное использование document.write происходит из примера HTML5 Boilerplate index.html.

<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.3.min.js"><\/script>')</script>

Я также видел ту же технику для использования json2.js JSON-анализа /stringify polyfill ( необходим для IE7 и ниже).

<script>window.JSON || document.write('<script src="json2.js"><\/script>')</script>

Это может заблокировать вашу страницу

document.write работает только во время загрузки страницы; Если вы позвоните по окончании загрузки страницы, она перезапишет всю страницу.

Это фактически означает, что вы должны вызывать его из встроенного блока сценария - и это не позволит браузеру обрабатывать последующие части страницы. Скрипты и изображения не будут загружены, пока блок записи не будет закончен.

Pro:

  • Это самый простой способ встраивания встроенного содержимого из внешнего (на ваш хост / домен) сценария.
  • Вы можете перезаписать весь контент в фрейме / фрейме. Раньше я часто использовал эту технику для элементов меню / навигации, прежде чем более современные методы Ajax стали широко доступны (1998-2002).

Против:

  • Он сериализует механизм рендеринга, чтобы сделать паузу до тех пор, пока не будет загружен внешний скрипт, что может занять гораздо больше времени, чем внутренний скрипт.
  • Обычно он используется таким образом, что сценарий размещается внутри содержимого, что считается дурным тоном.

Вот моя двойная ценность, в общем, вы не должны использовать document.write для тяжелой работы, но есть один случай, когда это определенно полезно:

http://www.quirksmode.org/blog/archives/2005/06/three_javascrip_1.html

Я обнаружил это недавно, пытаясь создать галерею слайдеров AJAX. Я создал два вложенных div и применил width/height а также overflow: hidden к внешнему <div> с JS. Это было так, что в случае, если в браузере была отключена JS, div будет плавать, чтобы разместить изображения в галерее - некоторое приятное изящное ухудшение.

Дело в том, что, как и в статье выше, это угон JS CSS не срабатывает, пока страница не загрузится, вызывая мгновенное мигание при загрузке div. Поэтому мне нужно было написать правило CSS или включить лист, когда страница загружена.

Очевидно, что это не сработает в XHTML, но, поскольку XHTML выглядит как "мертвая утка" (и отображается в IE как теговый суп), возможно, стоит пересмотреть ваш выбор DOCTYPE...

Он перезаписывает контент на странице, что является наиболее очевидной причиной, но я бы не назвал это "плохой".

Это просто не имеет большого смысла, если вы не создаете весь документ с использованием JavaScript, в этом случае вы можете начать с document.write.

Тем не менее, вы на самом деле не используете DOM, когда используете document.write- вы просто добавляете в текст большую часть текста, поэтому я бы сказал, что это дурной тон.

Он разбивает страницы с помощью рендеринга XML (например, страниц XHTML).

Лучше всего: некоторые браузеры переключаются обратно на рендеринг HTML, и все работает отлично.

Вероятно: некоторые браузеры отключают функцию document.write() в режиме рендеринга XML.

Хуже всего: некоторые браузеры будут генерировать ошибку XML при использовании функции document.write().

С верхней части моей головы:

  1. document.write необходимо использовать при загрузке страницы или загрузке тела. Поэтому, если вы хотите использовать скрипт в любое другое время для обновления содержимого страницы, document.write в значительной степени бесполезен.

  2. технически document.write будет обновлять только HTML-страницы, а не XHTML/XML. IE, кажется, довольно прощает этот факт, но другие браузеры не будут.

http://www.w3.org/MarkUp/2004/xhtml-faq

Хром может заблокировать document.write который вставляет скрипт в определенных случаях. Когда это произойдет, в консоли отобразится это предупреждение:

Скрипт с блокировкой синтаксического анализатора, перекрестный источник, ..., вызывается через document.write. Это может быть заблокировано браузером, если устройство плохо подключено к сети.

Рекомендации:

Нарушение браузера

.write считается нарушением браузера, так как останавливает анализатор от рендеринга страницы. Парсер получает сообщение о том, что документ изменяется; следовательно, он блокируется, пока JS не завершит свой процесс. Только в это время парсер возобновит работу.

Спектакль

Самым большим последствием использования такого метода является снижение производительности. Для загрузки содержимого страницы браузеру потребуется больше времени. Неблагоприятная реакция на время загрузки зависит от того, что записывается в документ. Вы не увидите большой разницы, если добавите <p> тег для DOM, а не для передачи массива из 50 ссылок на библиотеки JavaScript (что я видел в рабочем коде и привело к задержке в 11 секунд - конечно, это также зависит от вашего оборудования).

В общем, лучше избегать этого метода, если вы можете помочь ему.

Для получения дополнительной информации см. Вмешательство против document.write()

Основано на анализе, проведенном компанией Lighthouse Audit от Google-Chrome Dev Tools.

Я не думаю, что использование document.write - плохая практика. Проще говоря, для неопытных людей это как высокое напряжение. Если вы используете его неправильно, вы приготовитесь. Есть много разработчиков, которые хотя бы раз использовали этот и другие опасные методы, но никогда особо не разбираются в своих ошибках. Вместо этого, когда что-то идет не так, они просто спасаются и используют что-то более безопасное. Это те, кто делает такие заявления о том, что считается "плохой практикой".

Это похоже на форматирование жесткого диска, когда вам нужно удалить только несколько файлов, а затем сказать, что "форматирование диска - плохая практика".

  • Простая причина, почему document.write плохой практикой является то, что вы не можете придумать сценарий, в котором вы не можете найти лучшую альтернативу.
  • Другая причина в том, что вы имеете дело со строками, а не с объектами (это очень примитивно).
  • Это только добавить к документам.
  • Он не имеет ничего общего с красотой, например, шаблона MVC (Model-View-Controller).
  • Гораздо эффективнее представлять динамический контент с помощью ajax+jQuery или angularJS.

Можно рассматривать document.write() (и.innerHTML) как оценку строки исходного кода. Это может быть очень удобно для многих приложений. Например, если вы получаете HTML-код в виде строки из некоторого источника, удобно просто "оценить" его.

В контексте Lisp манипулирование DOM было бы похоже на манипулирование структурой списка, например, создание списка (оранжевого цвета) с помощью:

(cons 'orange '())

И document.write () - это как вычисление строки, например, создание списка путем оценки строки исходного кода, например:

(eval-string "(cons 'orange '())")

Lisp также обладает очень полезной способностью создавать код, используя манипуляции со списком (например, используя "стиль DOM" для создания дерева разбора JS). Это означает, что вы можете создать структуру списка, используя "стиль DOM", а не "стиль строки", а затем запустить этот код, например, так:

(eval '(cons 'orange '()))

Если вы реализуете инструменты кодирования, такие как простые живые редакторы, очень удобно иметь возможность быстро оценивать строку, например, с помощью document.write () или.innerHTML. Lisp идеален в этом смысле, но вы можете делать очень крутые вещи и в JS, и многие люди делают это, например, http://jsbin.com/

Недостатки document.write в основном зависят от этих 3 факторов:

а) Реализация

Document.write() в основном используется для записи контента на экран, как только этот контент необходим. Это означает, что это происходит где угодно, либо в файле JavaScript, либо внутри тега скрипта в файле HTML. При размещении тега script в любом месте такого HTML-файла плохая идея иметь операторы document.write() внутри блоков сценария, которые переплетаются с HTML внутри веб-страницы.

б) рендеринг

Хорошо спроектированный код в целом будет принимать любой динамически сгенерированный контент, сохранять его в памяти, продолжать манипулировать им, пока он проходит через код, прежде чем он, наконец, выплюнет на экран. Таким образом, чтобы повторить последний пункт в предыдущем разделе, рендеринг контента на месте может отображаться быстрее, чем другой контент, на который можно положиться, но он может быть недоступен для другого кода, который, в свою очередь, требует, чтобы контент отображался для обработки. Чтобы решить эту дилемму, нам нужно избавиться от document.write() и правильно реализовать ее.

в) невозможное манипулирование

Как только это написано, это сделано и закончено. Мы не можем вернуться, чтобы манипулировать этим без подключения к DOM.

Я думаю, что самая большая проблема заключается в том, что любые элементы, написанные через document.write, добавляются в конец элементов страницы. Это редко желаемый эффект с современными макетами страниц и AJAX. (вы должны помнить, что элементы в DOM являются временными, и когда скрипт запускается, это может повлиять на его поведение).

Гораздо лучше установить элемент-заполнитель на странице, а затем манипулировать его innerHTML.

Другие вопросы по тегам