JavaScript for..in和enum奇怪的行为

时间:2012-06-22 13:49:59

标签: javascript jquery

我遇到了JavaScript中for..in循环的奇怪行为问题。我有以下HTML:

<div id="quarter_circle_top_left">...</div>
<div id="quarter_circle_top_right">...</div>
<div id="quarter_circle_bottom_right">...</div>
<div id="quarter_circle_bottom_left">...</div>    

<div id="author_dimension"></div>
<div id="similar_dimension"></div>
<div id="citation_dimension"></div>
<div id="concept_dimension"></div>

我想要的是当我将鼠标悬停在其中一个“维度”(后4个div)上时,其中一个四分之一圆圈(前4个div)将突出显示。我在JS中有以下枚举:

var DIMENSIONS = {
    DIM_AUTHORS: {value: 1, dimCode: "author_dimension", areaCode: "quarter_circle_top_left"},
    DIM_SIMILAR: {value: 2, dimCode: "similar_dimension", areaCode: "quarter_circle_top_right"},
    DIM_CITATIONS: {value: 3, dimCode: "citation_dimension", areaCode: "quarter_circle_bottom_right"},
    DIM_CONCEPTS: {value: 4, dimCode: "concept_dimension", areaCode: "quarter_circle_bottom_left"}
};

这个for..in循环应该突出显示:

for (var key in DIMENSIONS) {
    $("#" + DIMENSIONS[key]['dimCode']).hover(
        function() {
            $("#" + DIMENSIONS[key]['areaCode']).addClass("hover");
        }, 
        function() {
            $("#" + DIMENSIONS[key]['areaCode']).removeClass("hover");
        }
    );
}

这种方法有效但发生的事情是“尺寸”没有突出显示相应的四分之一圆,而是悬停在任何一个圆上,只突出显示最后一个(左下角)四分之一圆。因此,当我将鼠标悬停在作者“维度”上时,我希望左上角的四分之一圆圈突出显示,但只突出显示最后一个(左下角)。

我尝试打印DIMENSIONS[key]['dimCode']DIMENSIONS[key]['areaCode']的值并且它们是正确的。我的代码无法按预期工作的任何想法?

5 个答案:

答案 0 :(得分:3)

正如@Cranio所说,这是循环/闭包问题。

由于您使用的是jQuery,因此可以使用$.each

$.each(DIMENSIONS, function(key, value) {
    // use value['dimCode'] instead of DIMENSIONS[key]['dimcode']
    ...
});

附加函数范围的引入避免了循环/闭包问题。

答案 1 :(得分:2)

因为key作为循环变量无法在闭包中引用。

答案 2 :(得分:2)

不完全针对您当前的情况进行修复,但我建议您使用密钥和dimCode作为键值对,而不是创建2D数组。

这应该可以正常工作:

var DIMENSIONS = {
    'author_dimension' : $('#quarter_circle_top_left'),
    // ... so on
};

所以你可以通过以下方式访问:

$('div[id*="_dimension"]').hover(function () {
    DIMENSIONS[this.id].addClass('hover');  
}, function () {
    DIMENSIONS[this.id].removeClass('hover');
});

似乎不那么复杂,每次执行悬停时都不必进行jQuery选择。

答案 3 :(得分:1)

http://jsfiddle.net/iambriansreed/YfhYk/

for (key in DIMENSIONS) {
    if(!DIMENSIONS.hasOwnProperty(key)) continue;  

    $("#" + DIMENSIONS[key].dimCode)
    .data('areaCode', DIMENSIONS[key].areaCode)
    .hover(function() {
        $("#" + $(this).data('areaCode')).addClass("hover");
    },function() {       
        $("#" + $(this).data('areaCode')).removeClass("hover");
    });
}​

答案 4 :(得分:0)

因为循环运行时定义了key。当发生实际的悬停事件时,它不会设置为相同的值。