仅调用多个select元素的最后附加onchange函数

时间:2017-05-26 19:12:59

标签: javascript html node.js web onchange

我正在以编程方式创建多个select元素,每个select元素中都有多个选项。我想以编程方式为每个select元素分配自己的onchange函数,该函数将提醒我select元素的相应id。

$(document).ready(function () {

    // Headers indicate how many select elements I need.
    // In this example, they are only used to initialize a unique select.id
    for (var ndx = 0; ndx < headers.length; ndx++) {
        var header = headers[ndx];
        const rowName = header.innerHTML;
        var select = document.createElement("select");
        var options = ["Contains", "Equals", "Starts with", "More than", "Less than", "Between", "Empty",
            "Doesn't contain", "Doesn't equal", "Doesn't start with", "Is not more than", "Is not between", "Is not empty"];

        select.id = rowName + "-select";
        options.forEach(function(option) {
            var element = document.createElement("option");
            element.value = option;
            element.innerHTML = option;
            select.appendChild(element);
        });
        select.onchange = function () {
            alert("select.id: " + select.id);
        }
    }
}

然而,在更改任何选择元素时,&#39;选项,仅警报中显示最后一个选择元素的ID。这可能是我不熟悉的javascript引用问题吗?谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

javascript中的变量被提升到声明它们的函数作用域的开头。实际上,这意味着每次迭代时,您都会使用新的选择框替换变量select。这意味着所有侦听器都将引用相同的select变量,该变量在循环的末尾将包含对最后创建的选择的引用。

<强>解决方案

将侦听器注册包装在IIFE(立即调用的函数表达式)中,并将其作为参数传递。这样,select的值将仅绑定到当前迭代。

(function(select) {
    select.onchange = function() {
        alert(select.id);
    }
})(select);

修改

实现侦听器的更正确的方法是使用传递给它的事件对象:

select.onchange = function(e) {
    alert(e.target.id); //e.target refers to the element that originated the event
}

但是我也离开了上面的答案,因为在你的代码中还存在与提升/作用域有关的问题,这是一个非常常见的错误。