【问题标题】:jquery performing calculation on dynamically generated elementsjquery对动态生成的元素执行计算
【发布时间】:2011-02-04 14:11:21
【问题描述】:

我有一个由一行 3 个输入元素组成的表格:价格、数量和总计。在此之下,我有两个链接可以单击以在表中动态生成另一行。所有这些都运行良好,但实际上计算总元素的值给我带来了麻烦。我知道如何计算第一个总元素的值,但是当我向表中添加新行时,我无法扩展此功能。这是html:

<table id="table" border="0">
    <thead>
        <th>Price</th><th>Quantity</th><th>Total</th>
    </thead>
<tbody>
<tr>
    <td><input id ="price" type = "text"></input></td>
    <td><input id ="quantity" type = "text"></input></td>
    <td><input id ="total" type = "text"></input></td>
</tr>
</tbody>
</table>
<a href="#" id="add">Add New</a>
<a href="#" id="remove">Remove</a>

这是我正在使用的 jquery:

$(function(){
  $('a#add').click(function(){
    $('#table > tbody').append('<tr><td><input id ="price" type = "text"></input></td><td><input id ="quantity" type = "text"></input></td><td><input id ="total" type = "text"></input></td></tr>');  
   });
  $('a#remove').click(function(){
  $('#table > tbody > tr:last').remove();
  });
});

$(function(){
    $('a#calc').click(function(){
    var q = $('input#quantity').val();
    var p = $('input#price').val();
    var tot = (q*p);
    $('input#total').val(tot);
    });
 });

我是 jquery 的新手,所以可能有一个我不知道的简单方法可以选择我想要计算的相关字段。任何指导将不胜感激。

【问题讨论】:

    标签: jquery dynamically-generated


    【解决方案1】:

    您不能有多个共享同一个 ID 的元素。 ID 在整个文档中必须是唯一的。

    也就是说,您必须更改代码才能使用类:

    <table id="table" border="0">
        <thead>
            <th>Price</th><th>Quantity</th><th>Total</th>
        </thead>
    <tbody>
    <tr>
        <td><input class="price" type = "text"></input></td>
        <td><input class="quantity" type = "text"></input></td>
        <td><input class="total" type = "text"></input></td>
    </tr>
    </tbody>
    </table>
    <a href="#" id="add">Add New</a>
    <a href="#" id="remove">Remove</a>
    

    还有:

    $(function(){
      $('a#add').click(function(){
        $('#table > tbody').append('<tr><td><input class ="price" type = "text"></input></td><td><input class ="quantity" type = "text"></input></td><td><input class ="total" type = "text"></input></td></tr>');  
       });
      $('a#remove').click(function(){
      $('#table > tbody > tr:last').remove();
      });
    });
    

    为了提供完整的解决方案,您的 ID 为 calc 的链接在哪里。计算应该如何进行?每一行应该有自己的calculation 按钮,还是有一个全局按钮来计算每一行的值?

    如果是后者,你可以使用这样的东西:

    $('a#calc').click(function(){
        $('#table tr').each(function() {
            $(this).find('.total').val(
                parseFloat($(this).find('.quantity').val())*
                parseFloat($(this).find('.price').val())
            );
        }
    }
    

    说明:

    当您单击该链接时,该函数将遍历表中的每一行,搜索类为 quantityprice 的输入字段,并将结果放入该行中类为 total 的输入中。

    请注意,我使用parseFloat 以确保使用数字进行计算。


    还请注意,您不必在创建的每一段 JS 代码周围都使用$(function(){})。将 在 DOM 加载后需要执行的所有内容(因为您从代码中访问元素)放入此函数中。所以你应该这样做:

    $(function() {
        $('a#add').click(function(){
             // .....
        }:
    
        $('a#calc').click(function(){
            // ...
        };
    }
    

    更新:如果你想使用.blur()方法,这里有一个例子:

    $('#table').delegate('input.total' , 'blur', function(){
        var row = $(this).closest('tr');
        $(this).val(
                $('.quantity', row).val())*
                $('.price', row).val())
        );
    });
    

    .closest() 获取与选择器匹配的最近父对象(在本例中为行),其余部分类似于我编写的第一个函数(获取特定行的值。

    我在这里使用较新的方法delegate(),但您也可以使用.live()。请注意,您必须使用其中一个,因为您正在动态创建行,并且在时间例如$(input.total).blur(function(){}) 将运行(当加载 DOM 时)尚未创建任何行。

    【讨论】:

    • 对不起,我的意思是从我的代码中删除 a#calc 并可能使用 jquery 的模糊和焦点事件,以便自动计算 .total 框。不过,您正在帮助我更好地理解这一点。谢谢。
    • 我尝试使用您的代码,但您的迭代器函数似乎不起作用(我点击了 calc 链接,但没有任何反应)
    • @user306472:嗯,我应该工作,我会再看一遍......请注意我关于使用的答案的更新,例如blur.
    • @user306472:你有没有在$(this).find('.total')...之前把你的HTML从使用ID改为使用classes? Otherwise it won't work. Also for debugging you should user Firefox with Firebug to check for any JS errors or just insert an alert()`来查看函数是否被调用。
    • 感谢您的帮助!我把一些东西命名错了。你的代码很好。
    【解决方案2】:

    您正在为这些新表行创建重复的“id”值。一个 id 在任何一个页面中应该是唯一的(它可以在多个页面上使用,但每页只能使用一次)。

    $('input#quantity') 只会返回它找到的 id 的第一个(或者可能是最后一个)实例,因为它不应该出现多次。

    解决方法是将所有 id 更改为 name=,然后执行以下操作(在伪代码中:

    var rows = $('table').getElementsByTagName('tr');
    for (var i = 0; i < rows.length; i++) {
        var q = ... extract quantity field from this row;
        var p = ... extract price field from this row;
        ... do calculation as usual
        ... store result in the total field in this row
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-27
      • 1970-01-01
      • 2014-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-17
      • 2015-11-05
      相关资源
      最近更新 更多