【问题标题】:Problem accessing the content of a div when that content came from an Ajax call当内容来自 Ajax 调用时,访问 div 的内容时出现问题
【发布时间】:2010-09-09 15:57:11
【问题描述】:

这是一个非常简单的原型示例。

它所做的只是在窗口加载时,将一些 html 粘贴到 div 中的 ajax 调用。

<html>
    <head>
        <script type="text/javascript" src="scriptaculous/lib/prototype.js"></script>
        <script type="text/javascript">
            Event.observe(window, 'load', function(){
                new Ajax.Request('get-table.php', {
                    method:  'get',
                    onSuccess:  function(response){
                        $('content').innerHTML = response.responseText;
                        //At this call, the div has HTML in it
                        click1();
                    },
                    onFailure:  function(){
                        alert('Fail!');
                    }
                });
                //At this call, the div is empty
                click1();
            });

            function click1(){if($('content').innerHTML){alert('Found content');}else{alert('Empty div');}}
        </script>
    </head>
    <body><div id="content"></div></body>
</html>

令人困惑的是 Prototype 理解 div 实际上包含内容的上下文。

如果您查看 ajax 调用的 onSuccess 部分,您会发现此时 $('content').innerHTML 包含一些内容。

但是,当我在 ajax 调用后立即检查 $('content').innerHTML 时,它似乎是空的。

这一定是我的一些基本误解。有人愿意给我解释一下吗?


编辑
我只是想澄清一点。我意识到 Ajax 调用是异步的。

这是执行事物的实际顺序以及为什么它让我感到困惑:

  1. 页面加载完毕。
  2. 向 get-table.php 发出 Ajax 请求。
  3. 在 onSuccess 内部调用 click1() 发生。我看到 div 有内容的警报。
  4. 在 Ajax 调用发生后对 click1() 的调用。我看到 div 为空的警报。

所以就像代码是按照它编写的顺序执行的,但是 DOM 并没有按照相同的顺序更新。


编辑 2 所以简短的回答是把代码放在 onSuccess 是正确的地方。

要考虑的另一种情况是您进行 Ajax 调用,然后从第一个调用的 onSuccess 进行另一个 Ajax 调用,如下所示:

new Ajax.Request('foo.php',{
  method:  'get',
  onSuccess:  function(response){
    doAnotherAjaxCall();
  }
});

function doAnotherAjaxCall(){
  new Ajax.Request('foo.php',{
    method:  'get',
    onSuccess:  function(response){
      //Anything that needs to happen AFTER the call to doAnotherAjaxCall() above
      //needs to happen here!
    }
  });
}

【问题讨论】:

  • 我已更新我的答案以说明您添加的信息。抱歉打扰了。

标签: javascript dom prototypejs


【解决方案1】:

AJAX 的第一个字母代表“异步”。这意味着 AJAX 调用是在后台执行的,即 AJAX 请求调用立即返回。这意味着代码通常在实际执行之后立即执行 onSuccess 处理程序被调用(甚至在 AJAX 请求完成之前)。

考虑到您编辑的问题:在某些浏览器(例如 Firefox)中,警告框并不像您想象的那样模态。即使另一个已经打开,异步代码也可能会弹出一个警告框。在这种情况下,较新的警报框(来自异步代码的警报框)会显示在旧警报框的顶部。这会产生异步代码首先执行的错觉。

【讨论】:

  • 请阅读我的编辑。您描述的流程在实践中并不完全准确。
  • 你说对了 :) Firefox 的行为肯定与你所描述的一样。但是,IE7 会首先从 onSuccess 内部显示警报,这非常令人困惑。
  • 我无法确认。 IE7 和我电脑上的 Firefox 做的事情完全一样,只是对话框会在不同的地方弹出,所以你可以实际看到发生了什么。
【解决方案2】:

您为处理 AJAX 调用而进行的函数调用的 onSuccess 元素在您收到来自 get-table.php 的响应时执行。这是一个单独的 Javascript 函数,当您从 get-table.php 获得答案时,您会告诉浏览器调用该函数。 AJAX.Request 调用下方的代码会在 AJAX.Request 调用后立即访问,但不一定在 get-table.php 调用之前。所以是的,我认为对 AJAX 的工作原理存在一些根本性的误解,可能是由于使用库来隐藏细节。

【讨论】:

    【解决方案3】:

    这是 Ajax 调用,它是异步的。这意味着在请求调用之后,响应还没有回来,这就是 $('content') 仍然为空的原因。

    【讨论】:

      【解决方案4】:

      没有尝试过您的代码:AJAX 调用是异步执行的。这意味着您的 Ajax.Request 触发,然后继续 click1() 调用,告诉您 div 为空。在此之后的某个时间点,Ajax 请求完成并且内容实际上被放入了 div。至此 onSuccess 函数被执行,你得到了你期望的内容。

      【讨论】:

        猜你喜欢
        • 2016-09-16
        • 1970-01-01
        • 2014-05-17
        • 1970-01-01
        • 2021-05-17
        • 1970-01-01
        • 2012-10-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多