Имея дело с JS-фреймворками, такими как AngularJS, Angular и React, я заметил, что прямое взаимодействие с DOM не рекомендуется и часто может приводить к ошибкам, если вы игнорируете предупреждения. Когда я говорю «взаимодействие с DOM», я имею в виду использование document.getElementById('myElement') и подобных методов для некоторых манипуляций или чтения значений из документа.
Мой вопрос по сути Почему?. Является ли это проблемой виртуальной DOM, когда React (например) не отслеживает фактическую DOM и, следовательно, будет застигнут врасплох, если вы внесете изменение «самостоятельно» без уведомления React и последующего обновления виртуальной DOM? Будет ли у Angular такая же проблема в таком случае?
Если кто-то знает только конкретный фреймворк, мне было бы очень интересно прочитать ответ на мой вопрос, даже если он не является обобщенным. Очевидно, я собираюсь еще раз погуглить, но я еще не видел здесь подобного вопроса, поэтому решил, что опубликую для потомков. Заранее благодарим за любые идеи!
Я не знаю, насколько уместны здесь архитектуры Model-View- *, но, по сути, думайте о дереве DOM как о представлении - вы не управляете представлением напрямую из чего-либо вне его. (И учитывая, что эти фреймворки абстрагируют само представление, можно с уверенностью предположить, что вы также не пишете свой собственный код представления.)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


@HDJEMAI дал ссылку на эту статью, которую я повторю, так как это хороший совет: https://www.reddit.com/r/javascript/comments/6btma7/whats_so_wrong_with_direct_dom_manipulation/
Я подробно остановлюсь на некоторых из этих причин ниже:
Есть много причин абстрагироваться от DOM, и ссылка на страницу Reddit в основном сосредоточена на «управлении состоянием», потому что ваша структура (Angular, React и т. д.), Скорее всего, будет делать предположения о состоянии DOM, которое будет нарушено, если вы напрямую манипулируете DOM, например:
function this_is_your_code() {
tell_angular_to_make_my_sidebar_500px_wide();
document.getElementById('mysidebar').style.width = 700px;
var sidebar_width = ask_angular_for_sidebar_width();
console.info( sidebar_width ); // will print "500px"
}
Другая причина абстрагироваться от DOM - убедиться, что ваш код работает с нетрадиционными DOM, помимо типичной среды DOM document / window веб-браузера, например, "серверный Angular" - это то, где часть кода Angular выполняется на сервере для предварительный рендеринг HTML для отправки клиенту, чтобы минимизировать задержку запуска приложения или разрешить веб-браузерам без JavaScript получать доступ к вашим веб-страницам, в этих ситуациях обычная модель W3C DOM больше не доступна, но доступна «поддельная» модель DOM, но она предоставляется Angular - и он работает только через абстракции Angular - он не будет работать, если вы напрямую манипулируете document, например:
function this_is_your_code_that_runs_in_nodejs() {
tell_angular_to_make_my_sidebar_500px_wide(); // this works and Angular's built-in abstraction of the DOM makes the appropriate change to the rendered server-side HTML
document.getElementById('mysidebar').style.width = 500px; // fails because `document` is not available
}
Спасибо за подробный ответ, @Dai, и спасибо за полезную ветку Reddit. Все было очень интересно и познавательно.
Действительно хороший ответ от @Dai выше, я хотел бы добавить к этому. В большинстве случаев вам не следует напрямую манипулировать dom. Бывают случаи, когда нужно, и это правильно.
Например, в React и Vue есть концепция ref. Это может быть похоже на идентификатор и дает вам доступ к узлу dom. Предположим, вы создаете приложение чата, в котором вы получаете старые чаты, когда пользователь прокручивает вверх, и вам нужно держать в фокусе последний видимый чат.
Такие ситуации есть, и нам нужен доступ к dom. Хорошая практика - держать такой код инкапсулированным и использовать каркасный способ доступа к чему-либо вместо обращения к документу / dom.