如何为每个带有数字的id元素使用Javascript函数

How to use a Javascript function for every element that has an id with a number attached

本文关键字:元素 id 函数 Javascript 数字      更新时间:2024-05-10

我正在尝试制作一个可以有多个条目的时间表,所以我设置了下表,但是,我不确定如何为每个"total"元素运行相同的函数。

<table width="100%" id="table" border="0">
  <tr id="headers">
    <td width="15%">Name</td>
    <td width="15%">Info</td>
    <td width="10%">Monday</td>
    <td width="10%">Tuesday</td>
    <td width="10%">Wednesday</td>
    <td width="10%">Thursday</td>
    <td width="10%">Friday</td>
    <td width="10%">Total</td>
  </tr>
  <tr id="1">
    <td width="15%">
      <input name="name1" id="name1">
    </td>
    <td width="15%">
      <input name="info1" id="info1">
    </td>
    <td width="10%">
      <input name="mo1" id="mon1">
    </td>
    <td width="10%">
      <input name="tue1" id="tue1">
    </td>
    <td width="10%">
      <input name="wed1" id="wed1">
    </td>
    <td width="10%">
      <input name="thu1" id="thu1">
    </td>
    <td width="10%">
      <input name="fri1" id="fri1">
    </td>
    <td width="10%" id="total1"></td>
  </tr>
  <tr id="2">
    <td width="15%">
      <input name="name2" id="name2">
    </td>
    <td width="15%">
      <input name="info2" id="info2">
    </td>
    <td width="10%">
      <input name="mon2" id="mon2">
    </td>
    <td width="10%">
      <input name="tues2" id="tue2">
    </td>
    <td width="10%">
      <input name="wed2" id="wed2">
    </td>
    <td width="10%">
      <input name="thu2" id="thu2">
    </td>
    <td width="10%">
      <input name="fri2" id="fri2">
    </td>
    <td width="10%" id="total2"></td>
  </tr>
  <!-- More here -->
</table>

因此,人们会把信息放在输入字段中,然后id="total[i]"会计算出一周的总数。然而,如果不为1、2、3等做单独的函数,我不知道如何为它们做for循环。

我建议您修改HTML代码,使每个tr都相同。这使得编写DRY代码变得更加容易,DRY代码可以在表中的tr的任何实例上工作,也使得将来的维护变得更加容易。为了实现这一点,您可以使用类来标识表中的tdinput元素,如下所示:

$('.day').change(calcRowTotals).change();
function calcRowTotals() {
  $('table tr:gt(0)').each(function() {
    var $row = $(this), total = 0;
    $row.find('.day').each(function() {
      total += parseInt($(this).val(), 10) || 0;
    });
    $row.find('.total').text(total);
  });
}
html {
  padding: 50px 0 0;
}
input {
  width: 90%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table width="100%" id="table" border="0">
  <tr id="headers">
    <td width="15%">Name</td>
    <td width="15%">Info</td>
    <td width="10%">Monday</td>
    <td width="10%">Tuesday</td>
    <td width="10%">Wednesday</td>
    <td width="10%">Thursday</td>
    <td width="10%">Friday</td>
    <td width="10%">Total</td>
  </tr>
  <tr>
    <td>
      <input name="name1" class="name">
    </td>
    <td>
      <input name="info1" class="info">
    </td>
    <td>
      <input name="mo1" class="mon day" value="1">
    </td>
    <td>
      <input name="tue1" class="tue day" value="2">
    </td>
    <td>
      <input name="wed1" class="wed day" value="3">
    </td>
    <td>
      <input name="thu1" class="thu day" value="4">
    </td>
    <td>
      <input name="fri1" class="fri day" value="5">
    </td>
    <td class="total"></td>
  </tr>
  <tr>
    <td>
      <input name="name2" class="name">
    </td>
    <td>
      <input name="info2" class="info">
    </td>
    <td>
      <input name="mon2" class="mon day" value="6">
    </td>
    <td>
      <input name="tues2" class="tue day" value="7">
    </td>
    <td>
      <input name="wed2" class="wed day" value="8">
    </td>
    <td>
      <input name="thu2" class="thu day" value="9">
    </td>
    <td>
      <input name="fri2" class="fri day" value="10">
    </td>
    <td class="total"></td>
  </tr>
  <!-- More here -->
</table>

如果您的合计列总是最后一列,则可以使用以下选择器:

tr td:last-child

否则,我建议将.total之类的类添加到所有这些元素中,并使用以下选择器对它们进行迭代:

.total

给定选择器,您可以使用此代码将某些内容应用于每个元素。

$(selector).each(function(){
    // here 'this' represents current being iterated matching element
});

根据Ali Rezas的建议,您应该在所有total元素中添加一个"total"类。

然后,你会做这样的事情:

$('.total').each(function(){
    // first, find the containing 'tr' element
    var parentRow = $(this).closest('tr');
    var total = 0;
    // then iterate over all inputs (you may want to give these all a class as well)
    parentRow.find('input.class').each(function(){
        total += $(this).val();
    })
})

表中有足够的结构,可以在不使用行和/或列ID的情况下执行数学运算。然而,在包含要相加的数字的单元格上添加class属性会在一定程度上简化它,同时使代码对DOM的任何未来更改都更有弹性。

在下面的代码中,我假设每个input都包含一个class="count"属性,并且最后一个单元格具有一个class="total"属性。

$('#table .total').each(function(_, $total) {
    // find desired input cells
    var $counts = $total.closest('tr').find('.count');
    // extract an array of their values
    var count = $counts.map(function(_, el) {
        return +el.value;
    }).get();
    // add their values
    var total = count.reduce(function(a, b) {
        return a + b;
    }, 0);
    // store result
    $total.text(total);    
});

(存在更简单的求和方法,但我喜欢.map/.reduce调用的函数风格)

这里有一个名为calculateRow的函数,用于提供前缀字母的每一行。

重要的是,以数字开头的id不能作为HTML选择器,所以我对您的id和进行了一些更改。因此,函数会查找字母。有关此的更多信息,请点击此处

function calculateRow(letter) {
  var inputs = document.querySelectorAll('#' + letter + ' [id$="'+ letter + '"]');
  var total = [].reduce.call(inputs, function(acc, next) {
    if (next.nodeName == 'INPUT' && next.value !== '') {
       return acc + parseInt(next.value)
    } else {
      return acc;
    }
  }, 0);
  return total;
}
document.querySelector('#getTotal-a').addEventListener('click', 
  function() {
    document.querySelector('#total-a').innerHTML = calculateRow('a');
}, false)
<table width="100%" id="table" border="0">
  <tr id="headers">
    <td width="15%">Name</td>
    <td width="15%">Info</td>
    <td width="10%">Monday</td>
    <td width="10%">Tuesday</td>
    <td width="10%">Wednesday</td>
    <td width="10%">Thursday</td>
    <td width="10%">Friday</td>
    <td width="10%">get Total</td>
    <td width="10%">Total</td>
  </tr>
  <tr id="a">
    <td width="15%">
      <input name="name1" id="name-a" value='1'>
    </td>
    <td width="15%">
      <input name="info1" id="info-a">
    </td>
    <td width="10%">
      <input name="mo1" id="mon-a">
    </td>
    <td width="10%">
      <input name="tue1" id="tue-a">
    </td>
    <td width="10%">
      <input name="wed1" id="wed-a">
    </td>
    <td width="10%">
      <input name="thu1" id="thu-a">
    </td>
    <td width="10%">
      <input name="fri1" id="fri-a">
    </td>
    <td width="10%">
      <button id=getTotal-a>tot</button>
    </td>
    <td width="10%" id="total-a">
    </td>
  </tr>
  </table>