等待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();});

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

首先,回调。它们可能很棘手!我发现,要想最好地了解它们,关键是通过将代码从这种情况中抽象出来,来可视化代码中发生的事情。请接受以下内容(请耐心等待):

你在亚马逊上买袜子。一旦你得到了你想要的袜子,你就会在城里穿它们,看起来超级华丽(这是肯定的)。所以你在电脑上找到了你想要的最好的袜子,然后点击"购买"。砰!他们两天后就到。

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

回调就是这样。他们会做一些事情(比如在亚马逊上订购袜子),而不是冻结你的代码,直到他们要求的东西回来,代码会继续前进。根据定义,回调是程序在进行异步调用时执行的一组任务(所以在本例中,"回调"是穿上袜子,在城里穿上它们)。

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

1) 穿着它们去健身房2) 在健身房穿3) 在从健身房回来的路上穿上它们

你把要用你的新袜子做的事情列出来。列表中的常见主题是什么?你有袜子!没有它们,你就不能做任何这些事情(至少,它们在列表中是如何指定的)。

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

祝你好运!

回调是指在从服务器获得响应后进行调用。你倒过来了。实际上,您需要将回调函数作为参数传递给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();})
});

最新更新