JavaScript/jQuery dropdownlist更改事件与关闭不起作用

JavaScript/jQuery dropdownlist change event with closure not working

本文关键字:不起作用 事件 jQuery dropdownlist JavaScript      更新时间:2023-09-26

在我的示例代码中,我有2个dropdownlist(但在实际代码中,由于dropdownlists是动态创建的,所以数量各不相同),我想做的是计算有多少个dropdowinlists是用非零值选择的。我使用闭包来跟踪具有非零值的下拉列表的总数。我成功地做到了(参考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); 
                };     
        }());
          });         
      });

提前谢谢。

附言:我也对不那么混乱的解决方案持开放态度。

问题

您正在从自执行匿名函数返回函数,但不要将返回的值附加到任何位置。

简化你的代码,看起来是这样的:

/* 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。我还更新了我的第一个代码片段,因此应该很容易发现这些变化:)

Ps.2.这只是一个快速修复,如上所述,要使代码可读,需要做很多工作。此外,每个函数都充当闭包,因此不要过度使用未分配给任何东西的自执行(function(){/* your code */})();(这很有用,但一个脚本一次就足够了)。相反,使用现有的闭包

我认为这应该有效:

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

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

这个怎么样?

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');       
}
);