如何最好地处理循环和事件监听器?

时间:2012-09-13 20:54:17

标签: javascript for-loop

我之前的问题 - Why JavaScript alerts allways 4 in when for-loop is for 3? - 表明在JS中为addEventListeners追赶for循环非常困难,所以我带来了一个粗暴的解决方案......我怎样才能正确地循环它让新手容易阅读?

document.getElementById('layerChangerOryginal').addEventListener('click', function() { Layer1() });
document.getElementById('layerChanger1').addEventListener('click', function() { Layer1() });
document.getElementById('layerChanger2').addEventListener('click', function() { Layer2() });
document.getElementById('layerChanger3').addEventListener('click', function() { Layer3() });

function Layer1() {
    document.getElementById('oryginalLayer1').className='container layer1';
    document.getElementById('oryginalLayer2').className='container layer2';
    document.getElementById('oryginalLayer3').className='container layer3';
}
function Layer2() {
    document.getElementById('oryginalLayer1').className='container layer3';
    document.getElementById('oryginalLayer2').className='container layer1';
    document.getElementById('oryginalLayer3').className='container layer2';
}
function Layer3() {
    document.getElementById('oryginalLayer1').className='container layer3';
    document.getElementById('oryginalLayer2').className='container layer2';
    document.getElementById('oryginalLayer3').className='container layer1';
}

2 个答案:

答案 0 :(得分:2)

for (var i = 1; i <= 3; i++) {
  document.getElementById('layerChanger'+i).addEventListener('click', window['Layer'+i]);
}

这是有效的,因为任何名为name的顶级函数或变量都是window[name]的值。

答案 1 :(得分:0)

这是使用循环的解决方案:

var a, i, j,
    eventFunc, 
    args_list = [[1, 2, 3], [3, 1, 2], [3, 2, 1]],

    str1 = 'container layer',
    str2 = 'oryginalLayer',
    byId = function(x) {
        return document.getElementById(x);
    };


for (i = 1; i < 4; ++i) {
    eventFunc = function() {
        for (j = 1; j < 4; ++j) {
            byId(str2 + j).className = str1 + args_list[i][j];
        }
    };

    byId('layerChanger' + i).addEventListener('click', eventFunc, false);

    if (i === 1) {
        byId('layerChangerOryginal').addEventListener('click', eventFunc, false);
        ++i;
    }
}​

似乎比下面的等效代码复杂一点:

var str = 'container layer',
    byId = function (x) {
        return document.getElementById(x);
    },

    createLayerFunc = function ( a, b, c ) {
        return function LayerX(x) {
            byId('oryginalLayer1').className = str+a;
            byId('oryginalLayer2').className = str+b;
            byId('oryginalLayer3').className = str+c;
        };
    },

    Layer1 = createLayerFunc(1, 2, 3),
    Layer2 = createLayerFunc(3, 1, 2),
    Layer3 = createLayerFunc(3, 2, 1);


byId('layerChangerOryginal').addEventListener('click', Layer1, false);
byId('layerChanger1').addEventListener('click', Layer1, false);
byId('layerChanger2').addEventListener('click', Layer2, false);
byId('layerChanger3').addEventListener('click', Layer3, false);