在继续之前等待AJAX​​响应

时间:2016-04-09 01:58:00

标签: javascript ajax

所以我看到这个问过很多次,但我发现的答案都没有。基本上我有一个AJAX函数,可以被许多其他函数调用。我的问题是在我有时需要在加载的元素上运行代码之后,例如添加事件侦听器。当然,脚本不等待元素完成加载我得到一个" document.getElementById(...)为null"错误。 我试过回电话,没有改变任何事情。 我试过同步AJAX。它破旧了。并没有工作。 我已经尝试在响应数据中运行JavaScript。正如这里的任何人都应该知道的那样,不起作用。

所以我错过了一些东西。有没有其他方法加载动态数据而不重新加载页面?有没有办法强制代码等待?解决方案是什么?

我的代码不起作用:

function ajax_call(page, target_tag, data)
{
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function()
    {
        if (xhttp.readyState == 4 && xhttp.status == 200)
        {
            target_tag.innerHTML = xhttp.responseText;
        }
    };
    xhttp.open("POST", page);
    xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhttp.send(data);
}

function edit_gallery(gallery)
{
    var target_tag= document.createElement("div");
    target_tag.style.position= "fixed";
    target_tag.style.top= "10px";
    target_tag.style.backgroundColor= "#FFFFFF";
    target_tag.style.padding= "10px";
    target_tag.style.margin= "0px auto";
    target_tag.id= "gallery_edit_window";

    document.getElementsByTagName("BODY")[0].appendChild(target_tag);
    ajax_call("/everythingapps/imagegallery/edit_gallery.php", target_tag, gallery);
    document.getElementById('gallery_save_btn').addEventListener('click', function() {save_gallery();});
}

function save_gallery()
{
    alert('test');
}

所以我的问题出在这个代码公园:

ajax_call("/everythingapps/imagegallery/edit_gallery.php", target_tag, gallery);
document.getElementById('gallery_save_btn').addEventListener('click', function() {save_gallery();});

那么任何想法?没有JS库。

编辑:我在回电时多次尝试。老实说,我很难理解它们。这是我的最后一次尝试:

function testing(callback)
{
    callback("/everythingapps/imagegallery/edit_gallery.php", target_tag, gallery)
}
testing(ajax_call);
document.getElementById('gallery_save_btn').addEventListener('click', function() {save_gallery();});

2 个答案:

答案 0 :(得分:1)

在从服务器获得响应后,将调用回调。你已经倒退了。实际上,您需要将回调函数作为参数传递给ajax_call。然后在onreadystatechange事件中,一旦收到服务器响应,就会调用回调。

像这样:

function ajax_call(page, target_tag, data, callbackFn)
{
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function()
    {
        if (xhttp.readyState == 4 && xhttp.status == 200)
        {
            target_tag.innerHTML = xhttp.responseText;
            callbackFn(); //INVOKE THE CALLBACK FUNCTION
        }
    };
    xhttp.open("POST", page);
    xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhttp.send(data);
}

然后当你调用ajax_call函数时,你会传入一个回调函数作为更新元素的最后一个参数:

ajax_call("/everythingapps/imagegallery/edit_gallery.php", target_tag, gallery, function() {
    //ajax call has completed so now we can update the element
    document.getElementById('gallery_save_btn').addEventListener('click', function() {save_gallery();})
});

您可以进行额外的更改以使事情更加灵活,并使您的ajax调用更通用,即将服务器响应传递给回调函数。如果您想要更新多个目标,则需要执行此操作。

callbackFn(xhttp.responseText); //INVOKE THE CALLBACK FUNCTION WITH DATA

然后你可以删除target_tag作为参数并执行此操作:

ajax_call("/everythingapps/imagegallery/edit_gallery.php", gallery, function(data) {
    //ajax call has completed so now we can update TWO ELEMENTS
    target_tag.innerHTML = data;
    document.getElementById('gallery_save_btn').addEventListener('click', function() {save_gallery();})
});

答案 1 :(得分:1)

所以这里有一些事情发生。

首先,回调。他们可能很棘手!我发现最好先了解它们,所有这些都是通过从代码中抽象代码来可视化代码中发生的事情。采取以下措施(并忍受我):

你在亚马逊购买袜子。一旦你得到你想要的袜子,你就可以在城里穿它们看起来超级浮华(这是肯定的)。因此,您在计算机上找到了所需的最好的袜子,然后点击“购买”。巴姆!他们将在2天内到达。

那很好,但现在呢?你想在接下来的两天里继续你的生活!当那些袜子到你家门口时,你会穿上它们 - 但在那之前,它一切照旧。

回调就像这样。他们做了一些事情(比如在亚马逊上订购袜子),而不是冻结你的代码,直到他们要求回来的东西,代码继续前进。根据定义,回调是程序在进行异步调用时执行的一组任务(因此在这个例子中,'回调'将放在袜子上并穿在城镇周围)。

所以这是一件事:你需要确保所有依赖于数据的东西(在例子中,来到你家的袜子)都留在回调函数中。继续这个荒谬的例子,假设你想用你的袜子做以下事情:

1)穿着他们开车到健身房 2)在健身房穿它们 3)在从健身房回来的路上穿上它们

你要列出与新袜子有关的清单。列表中的共同主题是什么?你有袜子!没有它们,你就不能做任何这些事情(至少,它们是如何在列表中指定的)。

这个冗长的响应如何与您的代码相关?好吧,看看你在进行AJAX调用后采取的步骤,以及每一步所依赖的步骤。基本上,如果任何代码假定您拥有该PHP文件中的任何内容,则需要在回调函数中使用它。

祝你好运!