【问题标题】:How can I elegantize this verbose jquery?如何优雅化这个冗长的 jquery?
【发布时间】:2016-04-26 16:12:52
【问题描述】:

我需要获取选中复选框的值(一次只允许选中一个),并且我有这个详细的代码:

if (!checkboxSelected) {
    return;
}

if($("#ckbx_produceusage").is(':checked')) {
    rptval = $('#ckbx_produceusage').val();
}
else if($("#ckbx_deliveryperformance").is(':checked')) {
    rptval = $('#ckbx_deliveryperformance').val();
}
else if($("#ckbx_fillrate").is(':checked')) {
    rptval = $('#ckbx_fillrate').val();
}
else if($("#ckbx_pricecompliance").is(':checked')) {
    rptval = $('#ckbx_pricecompliance').val();
}
setEmailAndGenerateValsForUnitReportPair(unitval, rptval);

有没有一种方法可以让这段代码不那么冗长而又不会让它变得难以理解?我想动态地将一个类添加到选中的复选框中,然后从之前添加过该类的任何内容中删除它,然后根据当前使用该类装饰的那个来获取 rptval。不过,这似乎有点臭或 Rubegoldbergesque,所以我正在寻找更好的解决方案。

更新

对于 T.J. Crowder,这里是 HTML(Razor/ASP.NET MVC 风格):

@foreach (var rpt in reports)
{
    @* convert id to lowercase and no spaces *@
    var morphedRptName = @rpt.report.Replace(" ", string.Empty).ToLower();
    <input class="ckbx leftmargin8" id="ckbx_@(morphedRptName)" type="checkbox" value="@rpt.report" />@rpt.report
}

【问题讨论】:

  • $('#all, #selectors').filter(':checked').first() 可能会带你到某个地方。
  • HTML 是什么样的?虽然我们可以在不改变的情况下改进它,但如果我们确实改变它,我们可能会改进更多。
  • @amphetamachine:这比我下面的回答好多了。你应该发布它。我应该尴尬地低下头。 ;-)
  • @amphetamachine 虽然简单,但如果没有检查任何错误,则不会处理错误。
  • 你为什么不给他们一个共同的类?那么你可以通过$(".class:checked").val() 来获取被选中的那个吗?

标签: jquery html css ischecked


【解决方案1】:
$(function()
{
...
// IF (these are the only elements that id starts with ckbx_) THEN
    rptval = $('[id^=ckbx_]').filter(':checked').val();
// ELSE
    // this syntax is more maintainable than $('#ckbx_produceusage, #ckbx_fillrate, ... selectors à la queue');
    rptval = $('#ckbx_produceusage').add('#ckbx_fillrate').add('#ckbx_deliveryperformance').add('#ckbx_pricecompliance').filter(':checked').val();
// FI
...
});

【讨论】:

  • *"这种语法比...更易于维护。" 在我看来,即使是远程也不行。
  • 第一行是我用的,所以不担心“else”
  • 谢谢,但它可能对其他人有帮助
  • @T.J.Crowder,两年前,我意识到当你说 远不及 时我从未理解过你的评论
【解决方案2】:

JQuery 集合是可过滤的,所以我建议使用以下方法:

// get value of first checked checkbox
var rptval = $(
   "#ckbx_produceusage,"+
   "#ckbx_deliveryperformance,"+
   "#ckbx_fillrate,"+
   "#ckbx_pricecompliance"
).filter(':checked').first().val();

注意:.first() 甚至可能是不必要的,因为.val() 获取集合中第一个元素的值。为便于阅读而保留。

【讨论】:

    【解决方案3】:

    在不更改 HTML 的情况下,您至少可以避免使用循环重复自己:

    ["#ckbx_produceusage", "#ckbx_deliveryperformance", "#ckbx_fillrate", "#ckbx_pricecompliance"].some(function(sel) {
        var e = $(sel);
        if (e.is(":checked")) {
            rptval = e.val();
            return true;
        }
    });
    setEmailAndGenerateValsForUnitReportPair(unitval, rptval)
    

    您可能会更改您的 HTML,以便初始数组可以是查询而不是 ID 选择器的硬编码列表。

    【讨论】:

      【解决方案4】:

      您还需要考虑未检查的情况。永远不要假设已经设置好了。

      function getValue(checkBoxes)
      {
          for ( var i = 0; i < checkBoxes.length; i++ )
          {
              var name = "#ckbx_" + checkBoxes[ i ];
      
              if ( $( name ).is( "checked" ) ) return $( name ).val();
          }
      
          //None were checked
          return null; //Should throw exception
      }
      
      rptval = getValue( [ "produceusage", "deliveryperformance", "fillrate", "pricecompliance" ] );
      

      【讨论】:

      • id 声明一个变量 length 并将其分配给 checkboxes.length 并在 for 循环中添加新变量,因此不会每次都计算长度
      • @AbdulAhmad 你误解了它是如何工作的。不是每次循环都编译长度。
      • 我说计算未编译。但我猜它不是每次都根据其他一些问题重新计算
      【解决方案5】:

      尝试使用 .each()

        $("input[type='checkbox']").each(function() {
          var rptval = 0;
          if ($(this).is(":checked")) {
            rptval = 1;
          }
          setEmailAndGenerateValsForUnitReportPair(unitval, rptval);
        });
      

      【讨论】:

      • 这对每个复选框调用该函数一次,这与OP的代码所做的不同。
      猜你喜欢
      • 2010-09-29
      • 2015-07-14
      • 2020-06-22
      • 1970-01-01
      • 2013-12-20
      • 1970-01-01
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多