所以我看到这个问题被问了很多次,但没有一个答案有效。基本上,我有一个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();})
});