Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么现代JavaScript框架不鼓励直接与DOM交互_Javascript_Angular_Reactjs_Dom_Web Frameworks - Fatal编程技术网

为什么现代JavaScript框架不鼓励直接与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,则会措手不及?在这种情况下,你会遇到同样的

在处理AngularJS、AngularJS和React等JS框架时,我注意到不鼓励直接与DOM交互,如果忽略这些警告,通常会导致bug。当我说“与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
    }
    

上面@Dai的回答非常好,我想补充一下。对于大多数情况,您不应该直接操作dom。有些情况下你必须这样做,这是正确的做法

例如,React和Vue有一个ref.的概念,它可以像一个id一样,允许您访问dom节点。假设您正在构建一个聊天应用程序,当用户滚动到顶部时,您将获取旧聊天记录,并且您需要保持最后可见聊天记录的焦点


这种情况存在,我们需要访问dom。好的做法是将这些代码封装起来,并使用框架方式访问某些内容,而不是接触文档/dom。

我不知道模型视图-*体系结构在这里有多重要,但本质上将dom树视为视图-您不会直接从其外部操作视图。(考虑到这些框架对视图本身进行了抽象,可以安全地假设您也没有编写任何自己的视图代码。)感谢您的详细回答,@Dai,并感谢您提供的有用的Reddit线程。这一切都很有趣,也很有见地。