循环到js对象

时间:2011-12-05 11:34:24

标签: javascript arrays object for-loop

我有这个js对象:

var tags = [{ 'x' : '42','y' : '25','id' : '1', 'linea' : '1'},{ 'x' : '378','y' : '24','id' : '2', 'linea' : '1'}];

我尝试以这种方式循环:

for(var i = 0; i < tags.length; i++){

            var x = tags[i].x -10;
            var y = tags[i].y -10;


            var offsetX = x + 20;
            var offsetY = y + 20;


            if( left >= x && left <= offsetX ){ 

                $(myDiv).bind('click',function(){
                    document.location.href = 'x.php?a='+ tags[i].linea +'&b=' + tags[i].id;
                }).css('cursor','pointer');

            }else{
                $(myDiv).unbind('click').css('cursor','none');
            }
        }

但我放松了第一个! 这是相关方式吗? 谢谢!

2 个答案:

答案 0 :(得分:2)

变量范围..更改为此,它应该可以正常工作:

var lineA = tags[i].linea;
var id = tags[i].id;
$(myDiv).bind('click',function(){
    document.location.href = 'x.php?a='+ lineA  +'&b=' + id;
}).css('cursor','pointer');

问题在于i是循环迭代器,因此当您单击myDiv时,它将始终具有最后一个值。

编辑:在查看之后,我可以看到你采取了错误的做法。你所追求的是确定用户在<div>内点击的位置,并根据你的阵列重定向到不同的位置。为此,这样的代码应该起作用:

var tags = [{ 'x' : '42','y' : '25','id' : '1', 'linea' : '1'},{ 'x' : '378','y' : '24','id' : '2', 'linea' : '1'}];

$("#myDiv").bind('click',function(event) {
    var left = event.pageX - $(this).position().left;
    for(var i = 0; i < tags.length; i++){    
        var x = tags[i].x -10;
        var y = tags[i].y -10;
        var offsetX = x + 20;
        var offsetY = y + 20;
        if( left >= x && left <= offsetX ){ 
            var lineA = tags[i].linea;
            var id = tags[i].id;
            document.location.href = 'x.php?a='+ lineA  +'&b=' + id;
            break;
        }
    }
});

代码应该非常清楚,无论如何它不可能只有部分元素带有手形光标 - 我建议你不要太乱,因为它会非常复杂

Live test case

编辑2 :使用不同光标的元素的“可点击”部分比我最初想象的要容易,你只需要处理onmousemove事件并在那里设置光标:

var posLeft = $("#myDiv").position().left;

$("#myDiv").bind('click',function(event) {
    var tag = GetHoveredTag(event);
    if (tag) {
        var lineA = tag.linea;
        var id = tag.id;
        document.location.href = 'x.php?a='+ lineA  +'&b=' + id;
    }
}).bind("mousemove", function(event) {
    var tag = GetHoveredTag(event);
    var cursor = (tag) ? "pointer" : "";
    $(this).css("cursor", cursor);
});

function GetHoveredTag(event) {
    var left = event.pageX - posLeft;
    for(var i = 0; i < tags.length; i++){    
        var x = tags[i].x -10;
        var y = tags[i].y -10;
        var offsetX = x + 20;
        var offsetY = y + 20;
        if( left >= x && left <= offsetX )
            return tags[i];
    }
    return 0;
}

Updated fiddle

答案 1 :(得分:2)

你没有松开第一个(听起来像是车钥匙)。您的问题是您的匿名函数,它在执行时关闭其父作用域(对于您的.bind()方法)。它创建了我们所说的 Closure

这是ECMAscript中一个非常常见的错误。您需要调用其他上下文来避免此问题。

$(myDiv).bind('click',(function( index ){
    return function() {
        document.location.href = 'x.php?a='+ tags[index].linea +'&b=' + tags[index].id;
    };
}( i ))).css('cursor','pointer');

如果不这样做,所有这些匿名函数上下文将在其作用域链中共享相同的父上下文。现在没有详细描述太多,最终所有事件处理程序都会引用相同的变量i

除此之外,看起来您将多个单击事件处理程序绑定到同一个元素myDIV。每个处理程序都会导致浏览器重定向到另一个url,因此,这会带来麻烦。我甚至无法判断第一个或最后一个处理程序是否会赢得这场比赛。