зацикливание и закрытие - PullRequest
0 голосов
/ 23 марта 2012

У меня есть некоторый код, который генерирует группу button элементов и добавляет их к div в body через некоторые функции DOM. Он динамически устанавливает группу анонимных функций ( обработчики событий ) на onclick событие каждого button.

Это выполняется путем итерации от 0 до 20.

Проблема в том, что я хочу использовать счетчик цикла, i, в обработчике событий - но, поскольку значение, которое оно находится на этой итерации в цикле, не достигает конечного значения i. Сначала я думал, что смогу сделать это через закрытие, но потом я понял, что это не работает так, как я думал, что будет изначально. i продолжает изменять каждую итерацию, и все другие анон-функции (через замыкание?) Должны видеть тот же i в том смысле, что область действия i указывает на одно и то же значение. Поскольку все они сообщают одно и то же значение, когда вы запускаете onclick.

Итак, я думаю, как я могу исправить это? Я попытался установить i для другой переменной и т. Д., Но все это приводит к тому же результату, поскольку значение этой новой переменной обновляется на каждой итерации так же, как i. Я думаю, что я упускаю что-то простое здесь.

<!DOCTYPE html>
<html>
<head>
    <title>loop closure test</title>

<script language="javascript" type="text/javascript">
window.onload = function() {

    var div = document.getElementById("myDiv");

    for( var i = 0; i <= 20; i++ ) {
        var b = document.createElement("button");
        b.setAttribute("type","button");
        b.appendChild(document.createTextNode("Button" + i.toString()));
        b.onclick = function(event) {
            var date = new Date( 2012, 3, i );
            alert( date.getMonth() + "/" + date.getDate() + "/" + date.getFullYear() );
        }       
        div.appendChild(document.createElement("br"));
        div.appendChild(b);
    }       
}
</script>

</head>

<body>
<div id="myDiv"></div>
</body>

</html>

Я подумал об этом еще немного, и пример ответа ниже. По сути, мне нужно было поймать i в другом закрытии. Я решил пойти по этому маршруту:

<!DOCTYPE html>
<html>
<head>
    <title>loop closure test</title>

<script language="javascript" type="text/javascript">
window.onload = function() {

    var div = document.getElementById("myDiv");

    for( var i = 0; i <= 20; i++ ) {        
        div.appendChild( (function() {
            var day = i;
            var b = document.createElement("button");
            b.setAttribute("type","button");
            b.appendChild(document.createTextNode("Button" + i.toString()));
            b.onclick = function(event) {
                var date = new Date( 2012, 3, day );
                alert( date.getMonth() + "/" + date.getDate() + "/" + date.getFullYear() );
            }


            return b;
        }()));

        div.appendChild(document.createElement("br"));

    }

}
</script>

</head>

<body>
<div id="myDiv"></div>
</body>

</html>

1 Ответ

1 голос
/ 23 марта 2012

Попробуйте использовать закрытие следующим образом:

var div = document.getElementById("myDiv");

for( var i = 0; i <= 20; i++ ) {
    var b = document.createElement("button");
    b.setAttribute("type","button");
    b.appendChild(document.createTextNode("Button" + i.toString()));
    b.onclick = function(pos) {
        return function(event) {
                var date = new Date( 2012, 3, pos );
                alert( date.getMonth() + "/" + date.getDate() + "/" + date.getFullYear() );
        }
    }(i);      
    div.appendChild(document.createElement("br"));
    div.appendChild(b);
}   ​
...