我有javascript代码,可以循环执行这些操作
div
元素,将其附加到dom
并获取其参考post
请求的函数innerHTML
这是代码
window.onload = function () {
var categories = document.getElementById('categories').children;
for (i = 0; i < categories.length; i++) {
var link = categories[i].children[1].children[0].attributes['href'].nodeValue;
var div = document.createElement('div');
div.className = "books";
div.style.display = "none";
categories[i].appendChild(div);
getLinks(link, div);
}
}
function getLinks(url, div) {
xhr = new XMLHttpRequest();
xhr.open('POST', 'ebook_catg.php', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
url = encodeURIComponent(url)
var post = "url=" + url;
xhr.node=div; //in response to Marc B's suggestion
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
xhr.node.innerHTML = xhr.responseText;
xhr.node.style.display = "block";
}
}
xhr.send(post);
}
现在当我在firebug
中查看时,我可以看到div
元素已创建并附加到categories
元素,其显示设置为hidden
。还发送了ajax post
个请求,并按预期收到响应。但是innerHTML
的{{1}}属性未设置,其显示也未设置为div
。
这意味着函数block
会丢失getLinks
引用。
当我在firefox控制台中输入div
时,它显示为console.log(div)
。
有人可以解释这里发生的事情吗?
为了回应Franks的评论,我将ReferenceError: div is not defined
更改为readystate
,并且我能够将最后一个ajax请求的响应附加到dom。所以很明显readyState
引用正在丢失。
答案 0 :(得分:2)
这是因为你正在使用一个不断被覆盖的公共(全局)变量div
。
在for loop
:
for (i = 0; i < categories.length; i++) {
var link = categories[i].children[1].children[0].attributes['href'].nodeValue;
var div = document.createElement('div'); //USE var!
div.className = "books";
div.style.display = "none";
categories[i].appendChild(div);
getLinks(link, div);
}
答案 1 :(得分:2)
请记住,在定义回调时,响应处理程序内部不会“固定”,因此div var的“当前”值不会嵌入到函数的定义中。它只能在函数实际执行时解析,到那时它可能已被设置为某个完全其他的div,或者由于父函数的范围已被破坏而被重置为null。
您可以将div值存储为xhr对象的数据属性,然后可以在回调中检索该对象:
xhr.data('thediv', div);
xhr.onreadystatechange = function () {
if (xhr.readystate == 4) {
div = xhr.data('thediv');
etc....
答案 2 :(得分:1)
好的,你有一些你不想要的全局变量。经验法则:除非您需要访问函数外部的变量,否则请在其前面放置var
。否则你将会在整个地方发现数据:
// changed the name to `d` because div seems to already be a global var.
function getLinks(url, d) {
// make xhr a local variable so it won't get re-written.
var request = new XMLHttpRequest();
request.open('POST', 'ebook_catg.php', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
url = encodeURIComponent(url)
var post = "url=" + url;
request.onreadystatechange = function () {
// when the request was global, this would be false until the last
// request completed
if (request.readyState == 4) {
// since d only exists as a parameter to getLinks, this should
// already be bound when the onreadystatechange is created.
d.innerHTML = request.responseText;
d.style.display = "block";
}
}
request.send(post);
}
那么,为什么我只是做这些奇怪的,奇怪的事情呢?好吧,看起来div被分配为全局变量,而JS 应总是查找函数参数名称进行绑定,我们希望消除所有可能的问题。所以我改变了那个变量的名字。然后我设置xhr以使用var关键字反映局部变量。我也更改了要求的名称。再一次,它应该无关紧要 - var意味着变量将绑定到该范围,但更改是无害的,因为我不知道你还有什么,我决定消除歧义。如果它对JS没有帮助,它至少会帮助读者。
上述答案的重要部分是在请求前面的var。
答案 3 :(得分:0)
这里我回答了我的问题。以下代码有效,我的意思是每篇文章的回复都附加到相应的div
元素。
var xhr=new Array();
window.onload=function() {
var categories=document.getElementById('categories').children;
for(i=0;i<categories.length;i++)
{
var link=categories[i].children[1].children[0].attributes['href'].nodeValue;
var div=document.createElement('div');
div.className="books";
div.style.display="none";
categories[i].appendChild(div);
getLinks(link,div,i);
}
}
function getLinks(url,div,i)
{
xhr[i]=new XMLHttpRequest();
xhr[i].open('POST','ebook_catg.php',true);
xhr[i].setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
url=encodeURIComponent(url)
var post="url="+url;
xhr[i].node=div;
xhr[i].onreadystatechange=function() {
if(xhr[i].readyState==4)
{
xhr[i].node.innerHTML=xhr[i].responseText;
xhr[i].node.style.display="block";
}
}
xhr[i].send(post);
}
我没有将其标记为已接受,因为我仍然不明白为什么我需要使用xhr
数组,因为本地xhr
对象应该足够了,因为每次{{1函数执行它具有onreadystate
对象的引用。现在,由于javascript函数也是对象,因此xhr
函数的每个实例都应该有自己的onreadystate
对象引用,因此我不需要创建xhr
s 的数组。
如果我错了,请纠正我