使用jQuery查找父元素和最近的元素

7

我有一个简单的表单,如下所示:

<tr>
    <td> <input type="text" name="qty[]" placeholder="qty"/> </td>
    <td> <input type="text" name="price[]" placeholder="price"/> </td>
    <td> <input type="text" name="total[]" placeholder="Total"/> </td>
</tr>

我们可以使用与上面相同的多行。

我需要的是,当用户输入qtyprice时,行total需要更新。

我尝试过的方法:

$('input[name=\'qty[]\']').on('change keyup', function(){
    var qty = $(this).val();
    var price = $(this).parent('tr').find('input[name=\'price[]\']').val();  
});

priceundefined

或者有更简单的方法吗?请查看Fiddle

更新:

.parent(..) 选择当前元素集合中每个元素的直接父元素。第一个参数筛选这个集合。你输入元素的直接父元素是 td 元素,而不是 tr 元素。

更新的Fiddle


2
.parent(..)选择集合中每个元素的父级,该父级由选择器进行筛选。直接的父级是 td,而不是 tr - Sumurai8
$(this).parent('td').parent('tr') - 可以工作! - epynic
或者只需使用.parent().parent();因为在该集合中您没有超过1个元素... - Sumurai8
5个回答

9
首先,考虑将您的HTML制作为以下方式:
<tr>
    <td> <input type="number" name="qty[]" placeholder="qty"/> </td>
    <td> <input type="number" name="price[]" placeholder="price"/> </td>
    <td> <input type="number" name="total[]" placeholder="Total"/> </td>
</tr>

另外,就 JavaScript 来说:

jQuery(document).on("change ,  keyup" , "input[name='qty[]'] , input[name='price[]']" ,function(){
     var parent_element = jQuery(this).closest("tr");
     var qty = jQuery(parent_element).find("input[name='qty[]']").val();
     var price = jQuery(parent_element).find("input[name='price[]']").val();
     if( qty.trim() != "" && price.trim() != "")
      {
        jQuery(parent_element).find("input[name='total[]']").val( parseFloat(qty) *parseFloat(price) );
      }
      else
      {
        jQuery(parent_element).find("input[name='total[]']").val("");
      }
});

编辑:更好的方法,正确考虑空字段。

你可以考虑添加以下代码: jQuery(document).on("change , keyup" , "input[name='qty[]'] , input[name='price[]'] , input[name='total[]']" ,function(){ 这样,如果有人试图手动更改总价,它将被重新计算。此外,你还可以在HTML标记中禁用总价(只需在<input blablabla disabled >标签内写入disabled即可)。 - Elentriel
1
дҪ еҸҜд»Ҙз”Ё parent_element жӣҝжҚўжүҖжңүзҡ„ jQuery(parent_element)гҖӮ.closest() жҖ»жҳҜиҝ”еӣһдёҖдёӘ jQuery еҜ№иұЎпјӣеңЁиҝҷйҮҢдҪҝз”Ё jQuery() 并没жңүд»»дҪ•еҘҪеӨ„гҖӮ - Matt
对我来说,这是一个规范化的问题,我更喜欢让jQuery决定我提供给它的是元素还是选择器(这样函数可以接收选择器和元素作为输入),所以我总是通过jQuery传递它。 - Elentriel
事件之间不应该有逗号,"change , keyup" 应该改为 "change keyup",否则只会处理 keyup 事件。另外,如果用户使用鼠标粘贴一些值怎么办?因为您在答案中使用了输入类型为数字的输入框,并且 input 事件比 type="number" 更好地支持,所以您应该改用以下方式:jQuery(document).on("input", "input[name='qty[]'], input[name='price[]']", handler); - A. Wolff
@Elentriel 很好的观点,但我会使用 readonly 布尔属性,以便让输入在 form 数据/序列化方面可提交。 - A. Wolff
显示剩余3条评论

4

只需将parent()更改为parents()

演示:

https://jsfiddle.net/yqe4kwbz/9/

引用自https://api.jquery.com/parents/关于parents()

获取当前匹配元素集合中每个元素的祖先,可以选择性地使用选择器进行过滤。 .parents()和.parent()方法类似,区别在于后者仅向上遍历DOM树一级。


3

我不确定您是否可以更改HTML代码,但如果您能够更改,我认为最好为您的 input 标签添加类名,例如以下示例:

<tr>
    <td> <input class='calculate' type="number" name="qty[]" placeholder="qty"/> </td>
    <td> <input class='calculate' type="number" name="price[]" placeholder="price"/> </td>
    <td> <input class='total' type="number" name="total[]" placeholder="Total"/> </td>
</tr>

使用class选择器来获取您的值:

$('.calculate']').on('change keyup', function(){
    var qty   = parseFloat( $(this).parents('tr').find('.qte').val() );
    var price = parseFloat( $(this).parents('tr').find('.price').val() );  

    $(this).parents('tr').find('.total').val( qty * price );  
});

希望这能有所帮助。

3
$('input[name=\'qty[]\']').on('change keyup', function(){
    var qty = $(this).val();
    var price = $(this).closest("tr").find('input[name=\'price[]\']').val();
});

尽管这段代码能够运行,但你需要处理很多验证问题。


2

.parent(..) 选择当前元素集合中每个元素的直接父元素。第一个参数筛选这个集合。你输入元素的直接父元素是td元素,而不是tr元素。

由于您的集合中只有1个元素,因此不需要进行筛选。只需获取父元素两次,以便选择tr元素。

$('input[name=\'qty[]\']').on('change keyup', function(){
    var qty = $(this).val();
    var price = $(this).parent().parent().find('input[name=\'price[]\']').val();  
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接