Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.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 js新手试图通过ajax理解dom(概念性)_Javascript_Jquery_Ajax_Dom - Fatal编程技术网

Javascript js新手试图通过ajax理解dom(概念性)

Javascript js新手试图通过ajax理解dom(概念性),javascript,jquery,ajax,dom,Javascript,Jquery,Ajax,Dom,我是一个python/数据的家伙,在一点web中混日子,基本上对JS和dom以及所有这些一无所知。所以发生了一些非常奇怪的事情,尽管我找到了一个解决办法,但我正在努力理解其中的原因 场景:常见问题 之前有一百万个这样的问题,“我有一些正在工作的jQuery/JS来处理一些HTML。然后,我没有硬编码相关的HTML,而是通过编程在其他地方创建了它,并通过AJAX将其拖入。突然,一切都崩溃了。” 答案总是这样:“你不能那样做。把你的代码连接到父子链的更高层,事件委托是一件神奇的事情,它会拯救你。”

我是一个python/数据的家伙,在一点web中混日子,基本上对JS和dom以及所有这些一无所知。所以发生了一些非常奇怪的事情,尽管我找到了一个解决办法,但我正在努力理解其中的原因

场景:常见问题

之前有一百万个这样的问题,“我有一些正在工作的jQuery/JS来处理一些HTML。然后,我没有硬编码相关的HTML,而是通过编程在其他地方创建了它,并通过AJAX将其拖入。突然,一切都崩溃了。”

答案总是这样:“你不能那样做。把你的代码连接到父子链的更高层,事件委托是一件神奇的事情,它会拯救你。”

所以,这发生在我身上,我花了一个小时左右的时间阅读之前的SOs,学习事件授权,事实上,它救了我,我的代码也起了作用

但我不明白为什么它一开始就坏了。所以我希望有人能向我解释基本的理论,这样我就能对整个dom有更深的理解

一些坏代码

$(document).ready(function(){

$("#autopubs").load("pubslist.html");
// Obviously, the stuff in pubslist.html is what the next line was 
// supposed to work on
$('.collapse').on('show.bs.collapse', function () {
    $('.collapse.in').collapse('hide');
});
});
对于这个解决方案可能没有什么意外。将autopubs包裹在一个外部分区中,并将折叠的东西挂到该分区上。做了,做了,非常不满意

但我仍然不明白为什么这是必要的。下面是我的心智模型,说明了那些被破坏的代码应该做什么

  • 好了,文件加载完毕!让我们执行我们的代码
  • 第一行:让我们获取这个文件并将其添加到DOM中。这在世界上是作为国家存在的,现在我们要对它进行变异,就像人们对国家所做的那样
  • 好的,现在它是DOM的一部分。那条线我们用完了。让我们转到下一行
  • 好的,现在我们想把一堆事件监听器连接到类崩溃的所有内容上。酷,让我们看看DOM的当前状态。嘿,看,里面有很多关于崩溃的东西。砰。连接好了
  • 除了4之外,没有发生过,因为第二行代码显然看不到第一行添加的所有内容

    直觉上,这有两个合理的原因:

  • 在第一行完成获取文件之前执行的第二行。如果这是真的,那么我学到了一些关于javascript(或jquery、或ajax等)的重要知识:行并不总是按顺序执行,或者至少不总是在下一行开始之前完成

  • 第一行实际上根本没有改变任何状态。DOM不是状态。是别的什么东西,什么东西。。。甚至可能是不变的?第一行完全修改了其他内容,第二行无法触及,因为它试图修改DOM


  • 老实说,这两种可能性对我来说都有点奇怪。但很明显,我根本就不明白这里到底发生了什么。有人能帮我吗?

    如果我理解正确,您应该只在“完整”回调中引用新加载的DOM。请看这里:


    JavaScript大量使用异步行为。行在同一个函数中按顺序执行,但这并不意味着它们“完成”了它们的操作

    如果查看
    load
    ()的文档,您可以看到它采用了可选的
    complete
    参数。这是一个回调。该函数将在操作完成时运行。调用
    load
    本身只会启动加载,有点“在后台”

    所以你可以这样做:

    $(document).ready(function(){
    
        $("#autopubs").load("pubslist.html", function() {
            $('.collapse').on('show.bs.collapse', function () {
                $('.collapse.in').collapse('hide');
            });
        });
    });
    
    要加载的回调在完成后运行


    为什么你最初的黑客解决方案真的有效?它将事件处理程序附加到现有的外部div,加载的HTML稍后在加载时放入其中

    第一行确实被执行了,它改变了状态。之后,您将一个事件连接到更改,并且每次有更改时都会调用该事件,但不是第一个,因为它在事件连接之前就已经发生了。

    您的第一个假设是正确的。当调用ajax时,它是异步的,这意味着它将在完成时运行回调。在本例中,jquery已经调用回调将内容追加到div中,但这可能发生在延迟大约100到200ms之后

    但是,另一段代码可以立即运行,但找不到任何内容,因为异步调用尚未完成

    在jQuery中,如果您查看文档,您将看到类似于
    (arg1,[arg2],[complete])
    的内容,其中complete将是一个闭包或回调函数

    如果将代码包装在该回调函数中而不是在其下方,则在加载和添加内容后将执行该代码

    编辑

    load也是jquery中方便/快捷的方法之一。有关更多文档,请查看

    此外,DOM是非常可变的,执行请求的第一行在DOM上执行操作。由于它是异步的,它会告诉脚本在等待数据时继续运行,这就是它失败的原因


    希望这有点帮助!您得到了正确的图片:)

    jQuery.load
    是异步的,这意味着您需要提供任何代码,以便在通过回调添加内容后执行。您在的底部有一个工作示例。

    正如其他人所说的那样,JavaScript在执行以下行之前不会等待完成加载函数。因此,您可以使用load函数(或任何其他需要时间的函数,如AJAX或animations)的回调参数。所以你的第一个假设是正确的。AJAX(AsynchronousJS)是一个巨大的东西,您应该深入研究它:)

    此外,您还可以在您的案例中使用委托:

    $(document).on('show.bs.collapse', '.collapse', function () {
        var collapse = $(this); // the individual $('.collapse') element triggering the event
    });
    
    这将绑定
    show.bs.collapse
    
    $(document).on('show.bs.collapse', '.collapse', function () {
        var collapse = $(this); // the individual $('.collapse') element triggering the event
    });
    
    $('.collapse').on()