IFFY函数在复选框上单击事件引发错误:checkbox.addEventListener(...)不是函数

时间:2018-07-12 11:45:07

标签: javascript function scope anonymous-function

我正在尝试使用循环内立即调用的函数来保存复选框状态。

问题从第54行开始。

(function(){

    var data = {
        days: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
        students: {
            'Slappy the Frog':    [true, true, true, true, true, true, true, true, true, true, true, true],
            'Lilly the Lizard':   [true, true, true, true, true, true, true, true, true, true, true, true],
            'Paulrus the Walrus': [true, true, true, true, true, true, true, true, true, true, true, true],
            'Gregory the Goat':   [true, true, true, true, true, true, true, true, true, true, true, true],
            'Adam the Anaconda':  [true, true, true, true, true, true, true, true, true, true, true, true]
        }
    }

    var app = {
        init: function(){
            view.init();
            view.render(data.students);
        },

        updateStudentsDays: function(student, day, isChecked){
            // console.log(student, day, isChecked);
            data.students[student][day] = isChecked;
        },

        calculateMissedDays: function(){

        }
    }

    var view = {
        init: function(){
            this.students = document.getElementById('students');
        },
        render: function(students){

            for (var key in students) {
                tr = document.createElement('tr');

                td = document.createElement('td');
                td.innerHTML = key;
                tr.append(td);

                for (var i = 0; i < students[key].length; i++) {

                    td = document.createElement('td');
                    checkbox = document.createElement('input');
                    checkbox.type = "checkbox";
                    if (students[key][i] === true) {
                        checkbox.checked = true;
                    } else {
                        checkbox.checked = false;
                    }

                    // problem is here
                    checkbox.addEventListener('click', function(key, i, checked){
                        return function(){
                            app.updateStudentsDays(key);
                        }
                    })(key, i, checkbox.checked);

                    td.append(checkbox)
                    tr.append(td);

                }

                this.students.append(tr);

            }

        }
    }

    app.init();

})();
body {
    line-height: 1.6;
    margin: 2em;
}

th {
    background-color: #001f3f;
    color: #fff;
    padding: 0.5em 1em;
}

td {
    border-top: 1px solid #eee;
    padding: 0.5em 1em;
}

input {
    cursor: pointer;
}

/* Column types */
th.missed-col {
    background-color: #f00;
}

td.missed-col {
    background-color: #ffecec;
    color: #f00;
    text-align: center;
}

.name-col {
    text-align: left;
}
body {
    line-height: 1.6;
    margin: 2em;
}

th {
    background-color: #001f3f;
    color: #fff;
    padding: 0.5em 1em;
}

td {
    border-top: 1px solid #eee;
    padding: 0.5em 1em;
}

input {
    cursor: pointer;
}

/* Column types */
th.missed-col {
    background-color: #f00;
}

td.missed-col {
    background-color: #ffecec;
    color: #f00;
    text-align: center;
}

.name-col {
    text-align: left;
}
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Udacity Attendance App</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="stylesheet" href="css/normalize.css">
        <link rel="stylesheet" href="css/style.css">
    </head>
    <body>
        <h1>Udacity Attendance</h1>

        <table>
            <thead >
                <tr>
                    <th class="name-col">Student Name</th>
                    <th>1</th>
                    <th>2</th>
                    <th>3</th>
                    <th>4</th>
                    <th>5</th>
                    <th>6</th>
                    <th>7</th>
                    <th>8</th>
                    <th>9</th>
                    <th>10</th>
                    <th>11</th>
                    <th>12</th>
                    <th class="missed-col">Days Missed-col</th>
                </tr>
            </thead>
            <tbody id="students"></tbody>
        </table>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
        <script src="js/app.js"></script>
    </body>
</html>

我不明白为什么会引发此错误。该复选框是合法的DOM元素。我在复选框上添加了一个事件处理程序。我应该能够将复选框状态(正确或错误)传递到立即调用的函数中。

1 个答案:

答案 0 :(得分:3)

您需要将右括号放在末尾。

checkbox.addEventListener('click', function(key, i, checked) {
    return function() {
        app.updateStudentsDays(key);
    }
}(key, i, checkbox.checked));
 ^ from                 to ^

(function(){

    var data = {
        days: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
        students: {
            'Slappy the Frog':    [true, true, true, true, true, true, true, true, true, true, true, true],
            'Lilly the Lizard':   [true, true, true, true, true, true, true, true, true, true, true, true],
            'Paulrus the Walrus': [true, true, true, true, true, true, true, true, true, true, true, true],
            'Gregory the Goat':   [true, true, true, true, true, true, true, true, true, true, true, true],
            'Adam the Anaconda':  [true, true, true, true, true, true, true, true, true, true, true, true]
        }
    }

    var app = {
        init: function(){
            view.init();
            view.render(data.students);
        },

        updateStudentsDays: function(student, day, isChecked){
            // console.log(student, day, isChecked);
            data.students[student][day] = isChecked;
        },

        calculateMissedDays: function(){

        }
    }

    var view = {
        init: function(){
            this.students = document.getElementById('students');
        },
        render: function(students){

            for (var key in students) {
                tr = document.createElement('tr');

                td = document.createElement('td');
                td.innerHTML = key;
                tr.append(td);

                for (var i = 0; i < students[key].length; i++) {

                    td = document.createElement('td');
                    checkbox = document.createElement('input');
                    checkbox.type = "checkbox";
                    if (students[key][i] === true) {
                        checkbox.checked = true;
                    } else {
                        checkbox.checked = false;
                    }

                    // problem is here
                    checkbox.addEventListener('click', function(key, i, checked){
                        return function(){
                            app.updateStudentsDays(key);
                        }
                    }(key, i, checkbox.checked));

                    td.append(checkbox)
                    tr.append(td);

                }

                this.students.append(tr);

            }

        }
    }

    app.init();

})();
body {
    line-height: 1.6;
    margin: 2em;
}

th {
    background-color: #001f3f;
    color: #fff;
    padding: 0.5em 1em;
}

td {
    border-top: 1px solid #eee;
    padding: 0.5em 1em;
}

input {
    cursor: pointer;
}

/* Column types */
th.missed-col {
    background-color: #f00;
}

td.missed-col {
    background-color: #ffecec;
    color: #f00;
    text-align: center;
}

.name-col {
    text-align: left;
}
body {
    line-height: 1.6;
    margin: 2em;
}

th {
    background-color: #001f3f;
    color: #fff;
    padding: 0.5em 1em;
}

td {
    border-top: 1px solid #eee;
    padding: 0.5em 1em;
}

input {
    cursor: pointer;
}

/* Column types */
th.missed-col {
    background-color: #f00;
}

td.missed-col {
    background-color: #ffecec;
    color: #f00;
    text-align: center;
}

.name-col {
    text-align: left;
}
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Udacity Attendance App</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="stylesheet" href="css/normalize.css">
        <link rel="stylesheet" href="css/style.css">
    </head>
    <body>
        <h1>Udacity Attendance</h1>

        <table>
            <thead >
                <tr>
                    <th class="name-col">Student Name</th>
                    <th>1</th>
                    <th>2</th>
                    <th>3</th>
                    <th>4</th>
                    <th>5</th>
                    <th>6</th>
                    <th>7</th>
                    <th>8</th>
                    <th>9</th>
                    <th>10</th>
                    <th>11</th>
                    <th>12</th>
                    <th class="missed-col">Days Missed-col</th>
                </tr>
            </thead>
            <tbody id="students"></tbody>
        </table>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
        <script src="js/app.js"></script>
    </body>
</html>