为什么现代JavaScript框架不鼓励直接与DOM交互
在处理AngularJS、AngularJS和React等JS框架时,我注意到不鼓励直接与DOM交互,如果忽略这些警告,通常会导致bug。当我说“与DOM交互”时,我的意思是使用为什么现代JavaScript框架不鼓励直接与DOM交互,javascript,angular,reactjs,dom,web-frameworks,Javascript,Angular,Reactjs,Dom,Web Frameworks,在处理AngularJS、AngularJS和React等JS框架时,我注意到不鼓励直接与DOM交互,如果忽略这些警告,通常会导致bug。当我说“与DOM交互”时,我的意思是使用document.getElementById('myElement')和类似的方法来执行一些操作或从文档中读取值 我的问题是为什么?。这是一个虚拟DOM问题吗?例如,React(例如)没有跟踪实际的DOM,因此,如果您“自己”进行更改,而没有通知React并随后更新虚拟DOM,则会措手不及?在这种情况下,你会遇到同样的
document.getElementById('myElement')
和类似的方法来执行一些操作或从文档中读取值
我的问题是为什么?。这是一个虚拟DOM问题吗?例如,React(例如)没有跟踪实际的DOM,因此,如果您“自己”进行更改,而没有通知React并随后更新虚拟DOM,则会措手不及?在这种情况下,你会遇到同样的问题吗
如果有人只知道一个特定的框架,我会非常有兴趣阅读我的问题的答案,即使它不是概括的。很明显,我会在谷歌上搜索更多,但我在这里还没有看到类似的问题,所以我想我会为子孙后代发帖。提前感谢您的任何见解 @HDJEMAI链接到这篇文章,我将重复这篇文章,因为这是一条很好的建议: 我将在下面详述其中一些原因:
- 像Angular和React这样的现代框架是为了隐藏DOM而设计的,因为它们想把DOM抽象出来。通过直接使用DOM,您打破了抽象,使您的代码对框架中引入的更改变得脆弱
- 想要抽象出DOM有很多原因,链接到的Reddit页面主要关注“状态管理”,因为您的框架(角度、反应等)可能会对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.log( sidebar_width ); // will print "500px" }
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 }
- 抽象DOM的另一个原因是,除了典型的web浏览器
/文档
DOM环境之外,还要确保您的代码能够与非传统的DOM一起工作,例如“DOM”是一个东西,如果服务器上运行一些Angular代码来预呈现HTML以发送到客户端,从而最大限度地减少应用程序启动延迟,或者允许没有JavaScript的web浏览器访问您的网页,那么在这些情况下,正常的W3C DOM不再可用,而是一个“假”DOMDOM是可用的,但它是由Angular提供的—它只通过Angular的抽象工作—如果您直接操作窗口
,它将不起作用,例如:文档
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.log( sidebar_width ); // will print "500px" }
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 }
这种情况存在,我们需要访问dom。好的做法是将这些代码封装起来,并使用框架方式访问某些内容,而不是接触文档/dom。我不知道模型视图-*体系结构在这里有多重要,但本质上将dom树视为视图-您不会直接从其外部操作视图。(考虑到这些框架对视图本身进行了抽象,可以安全地假设您也没有编写任何自己的视图代码。)感谢您的详细回答,@Dai,并感谢您提供的有用的Reddit线程。这一切都很有趣,也很有见地。