JavaScript / jQuery下拉列表更改事件,关闭不起作用

在我的示例代码中,我有2个下拉列表(但在实际代码中,数字因为下拉列表是动态创建的而有所不同)而我想要做的是计算使用非零值选择了多少下拉列表 。 我使用闭包来跟踪具有非零选定值的下拉列表总数。 我成功地做到了这一点(参见http://jsfiddle.net/annelagang/scxNp/9/ )。

旧/工作代码

$("select[id*='ComboBox']").each( function() { $(this).change( function() { compute(this); }); }); var compute = (function () { var total = 11; var selectedDdl = []; $("#total").text(total); return function (ctrl) { var id = $(ctrl).attr("id"); var ddlMeal = document.getElementById(id); var found = jQuery.inArray(id, selectedDdl); if (ddlMeal.options[ddlMeal.selectedIndex].value != 0){ if(found == -1){ total += 1; selectedDdl.push(id); } else{ total = total; } } else { total -= 1; var valueToRemove = id; selectedDdl = $.grep(selectedDdl, function(val) { return val != valueToRemove; }); } $("#total").text(total); }; }()); 

注意:我用11初始化了总变量,因为正如我在实际代码中提到的,我可以有2个以上的下拉列表,我只是想测试我的代码是否适用于超过2的值。

当我尝试在.change()事件中转移闭包时,它不再有效(请参阅http://jsfiddle.net/annelagang/scxNp/12/ )有人可以帮我解决这个问题吗? 我已经在这几天做了这段代码而且非常令人沮丧。

新/非工作代码:

 $("select[id*='ComboBox']").each( function() { $(this).change( function() { (function () { var total = 11; var selectedDdl = []; $("#total").text(total); return function (ctrl) { var id = $(ctrl).attr("id"); var ddlMeal = document.getElementById(id); var found = jQuery.inArray(id, selectedDdl); if (ddlMeal.options[ddlMeal.selectedIndex].value != 0){ if(found == -1){ total += 1; selectedDdl.push(id); } else{ total = total; } } else { total -= 1; var valueToRemove = id; selectedDdl = $.grep(selectedDdl, function(val) { return val != valueToRemove; }); } $("#total").text(total); }; }()); }); }); 

提前致谢。

PS我也对不太复杂的解决方案持开放态度。

我相信这应该有效:

 $("select[id*='ComboBox']").change(function() { $("#total").text($("select[id*='ComboBox'][value!=0]").length); }); 

http://jsfiddle.net/scxNp/15/

问题

您正在从自执行匿名函数返回函数,但不在任何地方确定返回值。

简化您的代码,它看起来像这样:

 /* some code here */ $(this).click(function(){ /** The following function is executed, returns result, but the * result (a function) is not assigned to anything, nor returned */ (function(){ /* some code here */ return function(ctrl){ /* some code here */ }; }()); }); /* some code here */ 

通常你的代码是非常难以理解的,你应该为了自己的利益而改进它(并避免这些问题)。 通过将参数传递给返回函数的函数(但没有调用它),可以快速修复上述问题。 解决方案在这里: jsfiddle.net/scxNp/13/

解决方案:解释

我做的很简单 – 我发现你从第一个(工作)示例传递给函数,但你甚至没有在第二个(不正确的)示例中执行此函数。 简化的解决方案如下所示:

 /* some code here */ $(this).click(function(){ /** Now the result of the following function is also executed, with * parameter passed as in your working example */ (function(){ /* some code here */ return function(ctrl){ /* some code here */ }; }())(this); }); /* some code here */ 

希望这有道理:)

PS。 我还更新了我的第一个代码片段,因此应该很容易发现更改:)

Ps.2。 这只是一个quickfix,并且 – 如上所述 – 要使代码可读,还有很多工作要做。 此外, 每个函数都作为闭包使用 ,所以不要过度使用自执行(function(){/* your code */})(); 您没有分配给任何东西(它很有用,但一次只需一个脚本就足够了)。 而是使用现有的闭包

这个怎么样?

HTML:

   

脚本:

 $(".howMany").change( function () { var nonZero = 0; $(".howMany").each( function () { if ($(this).val() != '0') ++nonZero; } ); $("#total").text('There are '+nonZero+' options selected'); } );