【问题标题】:Checkbox Trigger Event复选框触发事件
【发布时间】:2014-05-09 06:29:33
【问题描述】:

我遇到了复选框触发事件的问题。以下是我设置复选框的方式:

var content = "<table class=\"filter-table\">";
            content += "<tr><td><label><input  class=\"park_analysis_refined_e\"  type=\"checkbox\" onclick=\"toggleOverlayer('park_analysis_refined_e')\" checked='checked'>MP2008 Parks</label></td></tr>" +
                   "<tr><td><div id=\"park_analysis_refined_e\"></div></td></tr>";

            content += "<tr><td><label><input class=\"park_analysis_refined_b_e\"  type=\"checkbox\" id=\"cb_buffer\" onclick=\"toggleOverlayer('park_analysis_refined_b_e')\" >MP2008 Parks Buffer</label></td></tr>" +
                   "<tr><td><div id=\"park_analysis_refined_b_e\"></div></td></tr>";

            content += "<tr><td><label><input class=\"park_analysis_refined_a\"  type=\"checkbox\" onclick=\"toggleOverlayer('park_analysis_refined_a')\">DMP2013 Additional Parks</label></td></tr>" +
                   "<tr><td><div id=\"park_analysis_refined_a\"></div></td></tr>";

            content += "<tr><td><label><input class=\"park_analysis_refined_b_a\"  type=\"checkbox\" id=\"cb_additionalBuffer\" onclick=\"toggleOverlayer('park_analysis_refined_b_a')\">DMP2013 Additional Parks Buffer</label></td></tr>" +
                   "<tr><td><div id=\"park_analysis_refined_b_a\"></div></td></tr>";

            content += "</table>"

我有一个事件委托来检查某个复选框是否有事件,它将执行以下方法:

//Event delegation to maximize/minimize window
            $( "#cb_buffer" ).on( "click", function( event ) {
                   if($('#cb_buffer').is(':checked'))
                   {
                       selectionPGRefined();
                       maximisePGRWindow();
                   }
                   else
                   {
                       minimisePGRWindow();
                   }
               });
            $( "#cb_additionalBuffer" ).on( "click", function( event ) {
                   if($('#cb_additionalBuffer').is(':checked'))
                   {
                       selectionPGRefined();
                       maximisePGRWindow();
                   }
                   else
                   {
                       minimisePGRWindow();
                   }
               });

目前它运行良好。但是当我选中两个复选框并取消选中其他复选框时,就会出现问题。基本上我的程序是如何工作的,当用户选中第二个复选框时,它将添加一个覆盖图。同时,它会调用最大化窗口方法。第四个也是一样。

但是,当我同时选中第二个和第四个时,如果我取消选中第四个,maximizeWindow 应该使用第二个复选框值显示数据。相反,它只是关闭。

我想知道是否有任何替代方法让我循环遍历所有复选框,如果有选中或取消选中事件,然后执行其他操作。

编辑

function toggleOverlayer(id){
switchAnalytics(id);

if ($("."+id).prop("checked")) {
    showOverlayer(id);
} else {
    hideOverlayer(id);
}

}

    function switchAnalytics(id) {
        switch (id) {
            case 'park_analysis_refined_b_a':
                $("#pg_refined_selection").val("1").change();
                break;
            case 'park_analysis_refined_b_e':
                $("#pg_refined_selection").val("0").change();
                break;
        } }

function selectionPGRefined() {
    var selection = document.getElementById('pg_refined_selection');
    var selectionValues = selection.options[selection.selectedIndex].value;
    displayPGRefinedInfo(selectionValues);
}

/*Displaying results of park greenery refined*/
function displayPGRefinedInfo(values) {
    //alert(values);

    var para = "";
    if (values == "0") {
        para = "<br/>"
        para += "<p style='font-size:4.5em; color:#00297A; font-family:ArialVerdana;'>85.0%</p>";
        para += "<p>of residents live within 400m of park</p>";

    } else if (values == "1") {
        para = "<br/>"
        para += "<p style='font-size:4.5em; color:#00297A; font-family:ArialVerdana;'>90.0%</p>";
        para += "<p>of residents live within 400m of park</p>";
        para += "<p>*incl future DUs</p>"

    }
    document.getElementById('parkGreeneryRefinedBoxContent').innerHTML = para;
}

【问题讨论】:

  • 您确定您的事件委托有效吗?我不这么认为,因为 cb_buffer 和 cb_additionalBuffer 是动态创建的。
  • 是的,它确实有效,但一次只有一个。如果两个都选中,一个都没有选中,那么逻辑部分就出错了
  • 而不是click 事件使用change 事件。它最适合单选/复选框。
  • @AnoopJoshi 上面的event-delegation 方法将起作用,如果它是在创建动态元素fiddle1 之后编写的。否则它将无法工作fiddle2
  • @Praveen 没错。但在第一种情况下,他根本不需要事件委托

标签: javascript jquery checkbox


【解决方案1】:

尝试这样的委托:

$( elements ).on( events, selector, data, handler );

试试这样:

 $( document ).on( "change",'#cb_buffer', function( event ) {
                   if($(this).is(':checked'))
                   {
                       selectionPGRefined();
                       maximisePGRWindow();
                   }
                   else
                   {
                       minimisePGRWindow();
                   }
               });
 $( document).on( "change",'#cb_additionalBuffer', function( event ) {
                   if($(this).is(':checked'))
                   {
                       selectionPGRefined();
                       maximisePGRWindow();
                   }
                   else
                   {
                       minimisePGRWindow();
                   }
               });

api delegate doc sample demo

【讨论】:

    【解决方案2】:

    好的,我会尝试解决问题。有很多代码可以做一些非常简单的事情,但我知道根据这些代码可能还有其他功能。

    首先,既然您已经在使用 jQuery 事件,最好不要将它与标记中的 onclick 属性混合,所以让我们删除它并只使用 jQuery:

    var content = "<table class=\"filter-table\">";
                content += "<tr><td><label><input  class=\"park_analysis_refined_e\"  type=\"checkbox\" checked='checked'>MP2008 Parks</label></td></tr>" +
                       "<tr><td><div id=\"park_analysis_refined_e\"></div></td></tr>";
    
                content += "<tr><td><label><input class=\"park_analysis_refined_b_e\"  type=\"checkbox\" id=\"cb_buffer\" >MP2008 Parks Buffer</label></td></tr>" +
                       "<tr><td><div id=\"park_analysis_refined_b_e\"></div></td></tr>";
    
                content += "<tr><td><label><input class=\"park_analysis_refined_a\"  type=\"checkbox\">DMP2013 Additional Parks</label></td></tr>" +
                       "<tr><td><div id=\"park_analysis_refined_a\"></div></td></tr>";
    
                content += "<tr><td><label><input class=\"park_analysis_refined_b_a\"  type=\"checkbox\" id=\"cb_additionalBuffer\">DMP2013 Additional Parks Buffer</label></td></tr>" +
                       "<tr><td><div id=\"park_analysis_refined_b_a\"></div></td></tr>";
    
                content += "</table>"
    

    接下来,最好使用change 事件而不是click。我将更新函数以处理所有复选框,而不仅仅是第二个和第四个,如上所述。先前从onclick 标记属性执行的代码将在此处理程序中移动。其次,你应该合并这两个事件,因为它们做的事情基本相同,所以尽量避免不必要的代码重复。第三,在事件处理程序中,您应该检查是否选中了任何一个复选框,而不仅仅是当前的复选框。代码如下:

    $("input:checkbox").on("change", function (event) {
        toggleOverlayer($(this).prop('id'));
    
        if ($('#cb_buffer').is(':checked') || $('#cb_additionalBuffer').is(':checked')) {
            selectionPGRefined();
            maximisePGRWindow();
        }
        else {
            minimisePGRWindow();
        }
    });
    

    最后,让我们更改 switchAnalytics 函数以实现您将值设置为 0 或 1 的逻辑:

    function switchAnalytics(id) {
        var id_a = "park_analysis_refined_b_a";
        var id_e = "park_analysis_refined_b_e";
        var isChecked_a = $("#" + id_a).is(":checked");
        var isChecked_e = $("#" + id_e).is(":checked");
    
        if (id == id_a || id == id_e) {
            var newValue = "";
            if (isChecked_a && isChecked_e)
                newValue = id == id_a ? "1" : "0";
            else if (isChecked_a)
                newValue = "1";
            else if (isChecked_e)
                newValue = "0";
    
            $("#pg_refined_selection").val(newValue).change();
        }
    }
    

    让我知道这是否适合你。

    【讨论】:

    • 它确实有效,但不知何故它与我的 toggleOverlayer 发生冲突。我的冲突意味着如果我的第二个复选框被选中,下拉列表的值应该是 0。第四,它应该是 1。相反,它倒置了。检查我编辑的部分是否有 toggleOverlayer()
    • 我认为问题出在selectionPGRefined 函数上。你也可以发一下吗?
    • 有什么线索吗?我认为某些事件处理程序触发器部分出错了
    • 两个复选框都选中时,下拉列表的值应该是多少?
    • @StefanoDalpiaz 我无法删除 onclick,因为它已绑定到我的代码的其他部分。如果删除,它将导致错误,因为我的第一个复选框默认选中
    【解决方案3】:

    像下面这样使用多个 jQuery 选择器

    $( "#cb_buffer, #cb_additionalBuffer" ).on( "click", function( event ) {
      // here check if any of the checkbox is already checked then don't do any action
       var cb_buffer_checked = $("#cb_buffer").is(':checked');
       var cb_additionalBuffer_checked = $("#cb_additionalBuffer").is(':checked');
    
          // if checkbox unchecked then update option for other checked checkbox
          if(!$(this).is(':checked');)
          {
          // set option for checked checkbox
          if(cb_additionalBuffer_checked)
            switchAnalytics($("#cb_additionalBuffer").attr('id'));
    
          if(cb_buffer_checked )
            switchAnalytics($("#cb_buffer").attr('id'));
          }
    
          if(cb_buffer_checked || cb_additionalBuffer_checked)
          {
            selectionPGRefined();
            maximisePGRWindow();            
          }
          else
          {
           minimisePGRWindow();
          }
    
     });
    

    【讨论】:

    • 这只是缩短并让我的代码更整洁,但并不能解决问题。
    • 因此,如果选中 cb_buffer 和 cb_additionalBuffer 中的任何一个,您希望保持窗口最大化,如果两者都未选中,则将其最小化,对吗?如果我错了,请纠正我。
    • 是的,但随后出现了另一个问题。参见 Stefano Dalpiaz 的帖子。谢谢
    • 你想显示最后一个选中复选框的下拉值吗,我的意思是如果第一个复选框在第二个复选框之后选中,则选项值 = 0,反之亦然,则选项值 = 1。但是,如果两者都不受检查怎么办?你是通过调用 minimisePGRWindow() 来处理这个问题的吗?
    • 是的,没错。但是假设我两个都选中了,然后我取消选中一个,程序应该检查另一个是否被选中,如果选中,则显示该值
    猜你喜欢
    • 1970-01-01
    • 2015-08-09
    • 2011-11-17
    • 2016-04-13
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2013-02-02
    相关资源
    最近更新 更多