在我的示例代码中,我有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);
};
}());
});
});
提前致谢。
P.S。我也愿意接受更简洁的解决方案。
答案 0 :(得分:3)
您正在从自执行匿名函数返回函数,但不在任何地方确定返回值。
简化您的代码,它看起来像是:
/* 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/
我做的很简单 - 我发现你从第一个(工作)示例中将this
传递给函数,但是你甚至没有在第二个(不正确的)示例中执行此函数。简化的解决方案如下所示:
/* 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.2。这只是一个 quickfix ,并且 - 如上所述 - 要使您的代码可读,还有很多工作要做。另外每个函数都用作闭包,所以不要过度使用你没有分配给任何东西的自执行(function(){/* your code */})();
(它很有用,但是一个脚本应该足够一次)。而是使用现有的闭包。
答案 1 :(得分:2)
我相信这应该有效:
$("select[id*='ComboBox']").change(function() {
$("#total").text($("select[id*='ComboBox'][value!=0]").length);
});
答案 2 :(得分:0)
怎么样?
HTML:
<select id="ComboBox1" class="howMany">
<option value="0">Value 0</option>
<option value="1">Value 1</option>
<option value="2">Value 2</option>
<option value="3">Value 3</option>
</select>
<select id="ComboBox2" class="howMany">
<option value="0">Value 0</option>
<option value="1">Value 1</option>
<option value="2">Value 2</option>
<option value="3">Value 3</option>
</select>
<div id="total"></div>
脚本:
$(".howMany").change(
function ()
{
var nonZero = 0;
$(".howMany").each(
function ()
{
if ($(this).val() != '0')
++nonZero;
}
);
$("#total").text('There are '+nonZero+' options selected');
}
);