Почему современные JavaScript-фреймворки препятствуют прямому взаимодействию с DOM

Имея дело с JS-фреймворками, такими как AngularJS, Angular и React, я заметил, что прямое взаимодействие с DOM не рекомендуется и часто может приводить к ошибкам, если вы игнорируете предупреждения. Когда я говорю «взаимодействие с DOM», я имею в виду использование document.getElementById('myElement') и подобных методов для некоторых манипуляций или чтения значений из документа.

Мой вопрос по сути Почему?. Является ли это проблемой виртуальной DOM, когда React (например) не отслеживает фактическую DOM и, следовательно, будет застигнут врасплох, если вы внесете изменение «самостоятельно» без уведомления React и последующего обновления виртуальной DOM? Будет ли у Angular такая же проблема в таком случае?

Если кто-то знает только конкретный фреймворк, мне было бы очень интересно прочитать ответ на мой вопрос, даже если он не является обобщенным. Очевидно, я собираюсь еще раз погуглить, но я еще не видел здесь подобного вопроса, поэтому решил, что опубликую для потомков. Заранее благодарим за любые идеи!

whats_so_wrong_with_direct_dom_manipulation?
HDJEMAI 28.10.2018 04:33

Я не знаю, насколько уместны здесь архитектуры Model-View- *, но, по сути, думайте о дереве DOM как о представлении - вы не управляете представлением напрямую из чего-либо вне его. (И учитывая, что эти фреймворки абстрагируют само представление, можно с уверенностью предположить, что вы также не пишете свой собственный код представления.)

BoltClock 28.10.2018 05:22
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
12
2
783
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

@HDJEMAI дал ссылку на эту статью, которую я повторю, так как это хороший совет: https://www.reddit.com/r/javascript/comments/6btma7/whats_so_wrong_with_direct_dom_manipulation/

Я подробно остановлюсь на некоторых из этих причин ниже:

  • Современные фреймворки, такие как Angular и React, спроектированы так, чтобы скрыть DOM, потому что они хотят абстрагировать DOM. Используя DOM напрямую, вы нарушаете абстракцию и делаете свой код уязвимым для изменений, внесенных во фреймворк.
  • Есть много причин абстрагироваться от 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. Все было очень интересно и познавательно.

Ben Steward 28.10.2018 19:41

Действительно хороший ответ от @Dai выше, я хотел бы добавить к этому. В большинстве случаев вам не следует напрямую манипулировать dom. Бывают случаи, когда нужно, и это правильно.

Например, в React и Vue есть концепция ref. Это может быть похоже на идентификатор и дает вам доступ к узлу dom. Предположим, вы создаете приложение чата, в котором вы получаете старые чаты, когда пользователь прокручивает вверх, и вам нужно держать в фокусе последний видимый чат.

Такие ситуации есть, и нам нужен доступ к dom. Хорошая практика - держать такой код инкапсулированным и использовать каркасный способ доступа к чему-либо вместо обращения к документу / dom.

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