我今天晚上才开始使用此功能。然而,在经过一些小的编辑后,if / else的另一部分将被删除,其中一部分神奇地停止了工作。
json请求的回调函数中的四个for循环都执行,但实际上没有进行任何DOM操作。我已经三次检查是否存在适当的DOM元素。警报将在所有警报中触发。只是jQuery行失败了。
我已尝试将相关变量放入控制台并手动迭代数字以模拟循环。这很好用。我还使用警报来显示循环中变量的顺序,这些都可以正常运行。
我很困惑。
function drawPreview() {
var $preview = $('#preview');
$preview.remove();
$('#general_preview').remove();
try {
activecell.location;
}
catch (error) {
$('#active_cell').clone().attr('id','general_preview').appendTo('#win_preview');
return;
}
if (activecell.location.match(/^\d+_\d+$/)!==null) {
var x = parseInt(activecell.location.slice(0,activecell.location.indexOf("_")));
var y = parseInt(activecell.location.slice(activecell.location.indexOf("_")+1));
var area = "x"+activearea.join("x")+"x";
$('#win_preview').append($('<div id="preview"><div><div></div><div></div><div></div></div><div><div></div><div></div><div></div></div><div><div></div><div></div><div></div></div></div>'));
var i = y-1;
var j = x-1;
function loadCell() {
var exp = new RegExp("x"+i+"_"+j+"x","g");
if (area.match(exp)) {
if (i==y&&j==x) {
$('#active_cell').clone().children().unwrap().appendTo($preview.children().eq(1).children().eq(1));
++j;
loadCell();
}
else {
var jqxhr = $.getJSON('data/areas/'+$('#select_area').val()+'/'+x+"_"+y+'.json', function(data) {
var tmp = data;
for (var l=0; l<9; ++l) {
$preview.children().eq(i-y+1).children().eq(j-x+1).append('<div></div>');
}
for (var l=0; l<9; ++l) {
$preview.children().eq(i-y+1).children().eq(j-x+1).children().append('<div></div>');
}
for (var l = 0; l < 9; ++l) {
for (var m = 0; m < 9; ++m) {
$preview.children().eq(i-y+1).children().eq(j-x+1).children().eq(l).children().eq(m).attr("style","background: #"+tmp.p.c[tmp.c[l][m]-1]+" url(textures/terrain/"+tmp.p.t[tmp.t[l][m]-1]+".png) bottom center no-repeat");
}
}
if (i==y+1&&j==x+1) {
return;
}
else if (j==x+1) {
++i;
j = x-1;
loadCell();
}
else {
++j;
loadCell();
}
})
.error(function() { alert("There was an error loading the data. The data may be invalid or you may be looking for a file that does not exist."); })
}
}
else {
if (i==y+1&&j==x+1) {
return;
}
else if (j==x+1) {
++i;
j = x-1;
loadCell();
}
else {
++j;
loadCell();
}
}
}
loadCell();
}
}
答案 0 :(得分:3)
一开始,你称之为
var $preview = $('#preview');
然后,在第一个if
分支中:
$('#win_preview').append($('<div id="preview"><div...
这是好的,但在回调中,通过
$preview.children().eq(i-y+1).children()....
您正在尝试访问不再存在的元素。您需要获得刚刚添加的#preview
的新引用。也许在那个有<div></div>
吨附加的那一行之后:)
编辑:
另外,我建议你使用一些类选择器,而不是依赖于精确的DOM树结构(使用大量的eq()
)。如果你想以某种方式更新标记,它可能在将来节省你一些时间。此外,一旦你进入这个样式,你可以将这些选择器作为CSS样式副作用,所以为什么不立即使用它们。
另一件事:如果代码变得复杂且可读性不高,您可以尝试帮助自己进行一些调试:
for (var l=0; l<9; ++l) {
$preview.children().eq(i-y+1).children().eq(j-x+1).append('<div></div>');
}
也可以写成
var targetParent = $preview.children().eq(i-y+1).children().eq(j-x+1);
console.log(targetParent);
for (var l=0; l<9; ++l) {
targetParent.append('<div></div>');
}
你会在控制台中看到(假设是firefox + firebug调试),你正准备追加到哪里。这样做的另一个好处是它可以帮助您优化代码 - 您只需要追加目标一次,然后在循环中追加它。以前的变体既可以获得目标,也可以在循环中追加。
答案 1 :(得分:0)
我已经做了一个相当标准的重构来减少嵌套if语句的数量(这是逻辑错误和混乱的常见滋生地)。我鼓励你发布一些测试数据(如果你愿意,还有一个夹具),你希望这些数据能够真正发挥作用。一段有效的dom和一个单元数据样本应该足够了。
function drawPreview() {
var $preview = $('#preview'),
x, y, area, i, j;
function repeat( text, count ){
var i=0, out = '';
for( ; i++ < count ; ) {
out += text;
}
return out;
}
$preview.remove();
$('#general_preview').remove();
try {
activecell.location;
}
catch (error) {
$('#active_cell').clone().attr('id','general_preview').appendTo('#win_preview');
return;
}
if (activecell.location.match(/^\d+_\d+$/) === null ){
return;
}
x = parseInt(activecell.location.slice(0,activecell.location.indexOf("_")), 10);
y = parseInt(activecell.location.slice(activecell.location.indexOf("_")+1), 10);
area = "x"+activearea.join("x")+"x";
$('#win_preview').append($('<div id="preview"><div>' + repeat('<div>' + repeat('<div></div>', 4) + '</div>', 3) + '</div></div>'));
i = y-1;
j = x-1;
function loadCell() {
var exp = new RegExp("x"+i+"_"+j+"x","g"),
sel_area;
if (! area.match(exp)){
if (i==y+1&&j==x+1) {
return;
}
else if (j==x+1) {
++i;
j = x-1;
loadCell();
}
else {
++j;
loadCell();
}
return;
}
if (i==y&&j==x) {
$('#active_cell').clone()
.children()
.unwrap()
.appendTo($preview.children()
.eq(1)
.children()
.eq(1)
);
++j;
loadCell();
return;
}
var sel_area = $('#select_area').val();
var jqxhr = $.getJSON('data/areas/'+ sel_area +'/'+x+"_"+y+'.json', function(data) {
var tmp = data, l = 0, m = 0;
for ( l=0; l<9; ++l ) {
$preview.children()
.eq(i-y+1)
.children()
.eq(j-x+1)
.append('<div></div>');
}
for ( l=0; l<9; ++l) {
$preview.children()
.eq(i-y+1)
.children()
.eq(j-x+1)
.children()
.append('<div></div>');
}
for ( l = 0; l < 9; ++l) {
for ( m = 0; m < 9; ++m) {
$preview.children()
.eq(i-y+1)
.children()
.eq(j-x+1)
.children()
.eq(l)
.children()
.eq(m)
.css({background: "#"+tmp.p.c[tmp.c[l][m]-1]+" url(textures/terrain/"+tmp.p.t[tmp.t[l][m]-1]+".png) bottom center no-repeat"});
}
}
if (i==y+1&&j==x+1) {
return;
}
else if (j==x+1) {
++i;
j = x-1;
loadCell();
return;
}
++j;
loadCell();
return;
}).error(function() { alert("There was an error loading the data. The data may be invalid or you may be looking for a file that does not exist."); });
}
loadCell();
}