如何使此功能更通用?

How do I make this function more generic?

我有一个 jQuery 函数可以计算一些输入。我希望能够使它更通用,这样我就不必重复这段代码。

jQuery(document).ready(function(){
    update_amounts();
    jQuery('.list_item_9 input:not([readonly])').change(function() {
        update_amounts();
    });
});

function update_amounts() {
    var sum = 0;
    jQuery('.list_item_9 input:not([readonly])').each(function() {
        sum += Number(jQuery(this).val());
    });
    jQuery('.list_item_9 .gfield_list_184_cell5 input').val(sum);
}

此 HTML 如下所示:

<tr class="gfield_list_group list_item_9">
    <td class="gfield_list_cell">
        <input type="text" name="FIELDLABEL" value="" readonly="">
    </td>
    <td class="gfield_list_cell">
        <input type="text" name="TWO" value="">
    </td>
    <td class="gfield_list_cell">
        <input type="text" name="THREE" value="">
    </td>
    <td class="gfield_list_cell">
        <input type="text" name="FOUR" value="">
    </td>
    <td class="gfield_list_cell gfield_list_184_cell5">
        <input type="text" name="TOTAL" value="0" readonly="">
    </td>
</tr>

我已经对此进行了多次迭代,但我无法完全弄清楚如何根据已更改的内容来定位该功能。

这段代码应该可以满足您的需求。每次输入更改时,它都会找到父 gfield_list_group class 元素,然后将其下方的所有非只读输入相加,将总数写入带有 name="TOTAL" 的输入(您可能想要将其更改为 class 说明符,例如 glist_total_cell)。对于初始化,有一个例程 update_all_amounts 对所有 gfield_list_group 元素下的输入求和。

jQuery(document).ready(function() {
  update_all_amounts();
  jQuery('.gfield_list_group input:not([readonly])').change(function() {
    update_amounts(jQuery(this));
  });
});

function update_amounts(inp) {
  var sum = 0;
  var parent = inp.closest('.gfield_list_group');
  parent.find('input:not([readonly])').each(function() {
    sum += Number(jQuery(this).val());
  });
  parent.find('input[name="TOTAL"]').val(sum);
}

function update_all_amounts() {
  jQuery('.gfield_list_group').each(function() {
    update_amounts(jQuery(this).find('input:not([readonly])').first());
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr class="gfield_list_group list_item_9">
    <td class="gfield_list_cell">
      <input type="text" name="FIELDLABEL" value="row 9" readonly="">
    </td>
    <td class="gfield_list_cell">
      <input type="text" name="TWO" value="">
    </td>
    <td class="gfield_list_cell">
      <input type="text" name="THREE" value="6">
    </td>
    <td class="gfield_list_cell">
      <input type="text" name="FOUR" value="">
    </td>
    <td class="gfield_list_cell gfield_list_184_cell5">
      <input type="text" name="TOTAL" value="0" readonly="">
    </td>
  </tr>
  <tr class="gfield_list_group list_item_10">
    <td class="gfield_list_cell">
      <input type="text" name="FIELDLABEL" value="row 10" readonly="">
    </td>
    <td class="gfield_list_cell">
      <input type="text" name="TWO" value="4">
    </td>
    <td class="gfield_list_cell">
      <input type="text" name="THREE" value="">
    </td>
    <td class="gfield_list_cell">
      <input type="text" name="FOUR" value="">
    </td>
    <td class="gfield_list_cell gfield_list_184_cell5">
      <input type="text" name="TOTAL" value="0" readonly="">
    </td>
  </tr>
</table>

下面的演示非常通用——没有 ID、类 或属性选择器——只使用了 tagNames

  • 将所有内容包装到 <form> 中并将“输入”或“更改”事件委托给它。
  • <input>type改为number
  • 记得在计算之前将输入的每个值转换为实数。
  • 不要使用 <input readonly> 而是使用 <output></ouput>

演示

详情在demo中评论

// Delegate the input event to the <form>
$('form').on('input', function(e) {
  // Declare sum at 0
  var sum = 0;
  // On each <input>
  $(this).find('input').each(function() {
    // Convert the value of each input and add it to sum
    sum += Number($(this).val());
  });
  // Assign sum to the last <output>
  $('output:last').val(sum);
});
form {
  margin: 50px auto
}
<form>
  <table>
    <tr>
      <td>
        <output>Name</output>
      </td>
      <td>
        <input type="number" value='0'>
      </td>
      <td>
        <input type="number" value='0'>
      </td>
      <td>
        <input type="number" value='0'>
      </td>
      <td>
        <output>0</output>
      </td>
    </tr>
  </table>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>