1

I have this PHP script that generates a form:

for ($i = 1; $i <= 10; $i++) {
    echo "<tr class='vraagrij'><td><select name='select" . $i . "'><option>1</option>  <option>2</option></select></td><td><input type='text' value='Test' name='select" . $i . "'></td><td><select name='selectdos" . $i . "'><option>A</option><option>B</option></select></td></tr>";
}

What I need is to update the text in the input field of a specific row ONCE, whenever any element in that row has changed. So far I came up with this (I use css('color', 'yellow') for convenience and to easily see the behavior). But it only updates the changed element, and only once (since changed is set to 1, so I would need a new 'changed' per row, but I don't know how many rows there are going to be).

 $( document ).ready(function() {
    var changed = 0;

    $('.vraagrij').children().change(function(e) {
        if(clicked = 0)
        {
            var $parent = $(e.target).parent();
            var $kids = $parent.children("input");
            $kids.css('color', 'yellow');
            changed = 1;
        }
    });
});
4

4 回答 4

3

方法1:每行关闭

这是一个小提琴

您可以做的是使用each 函数为每一行创建一个闭包,在这种情况下,每一行都有自己的更改变量。

此外,您可以使用on() jQuery 函数间接绑定事件侦听器,而不是直接绑定到输入元素。

注意:输入不是直接来自行元素的子元素,因此也将children()交换为find()

$( document ).ready(function() {

  // Using the each function to create
  // a row specific closure
  $('.vraagrij').each(function() {

    // Track the state per row
    var changed = false

        // Create a variable to reference the
        // row directly in the change listener
      , $row = $(this);

    // Use event delegation to bind to all
    // descendant selects of the row efficiently
    $row.on("change", "select", function(e) {

      // Make sure the following only runs once
      // per row
      if(!changed) {
        changed = true;

        // Do something to the input, changing
        // color for testing purposes
        var $kids = $row.find("input");
        $kids.css('color', 'yellow');

      }
    });

  });

});

方法二:DOM查询/遍历

另一个小提琴

此方法使用 DOM 的状态来跟踪更改的状态:

$(document).ready(function() {

  // Again using event delegation to bind events
  // efficiently
  $(".vraagrij").on("change", "select", function(e) {

    // Collect the parent row
    var $row = $(this).closest("tr");

    // Check if it has already got the
    // changed class
    if(!$row.hasClass("changed")) {

      // Add the changed class in to track
      // the state and prevent this being
      // run again for the same row
      $row
        .addClass("changed")

        // Perform the action for the changed
        // select
        .find("input")
          .css("color", "yellow");
    }
  });

});

方法3:使用一种方法

另一个小提琴

one 方法处理事件一次。

更新包括来自billyonecan的重要建议,以使用closest("tr")代替parents("tr:eq(0)")parents("tr").first()

$(document).ready(function() {

  // Again using event delegation to bind events
  // efficiently, this time using the one method
  $(".vraagrij").one("change", "select", function(e) {

    // Perform the action for the changed
    // select
    $(this).closest("tr").find("input").css("color", "yellow");
  });

});
于 2013-05-17T07:57:26.477 回答
2

只需在每个更改的 tr 处添加一个新类:

$('.vraagrij').on("change","input,select",function(e){
    $parent_tr=$(this).closest('tr');
    if (!$parent_tr.hasClass('changed'))
    {
      $parent_tr.addClass('changed');
      $parent_tr.find("input").css('color', 'yellow');
    }
});

小提琴

于 2013-05-17T08:15:07.590 回答
0
if(clicked = 0)

it should be

if(clicked == 0)
于 2013-05-17T07:52:20.220 回答
0

我不知道是什么clicked或是changed为了什么,但您的if语句当前值设置clicked为 0,而不是将其与 0 进行比较。===在这种情况下,您应该使用:

if(clicked === 0)

您还应该使用 jQuery 的.on()事件处理程序。

你的代码做了很多不必要的事情。您应该使用 CSS开始选择器( ^=):

// Select with a name beginning with "select", e.g. "select3"
$('.vraagrij').on('change', 'select[name^="select"]', function() {
    if(clicked === 0)
    {
        var
            name = $(this).attr('name'), // "select3", for instance
            $input = $('input[name="' + name + '"]') // input[name="select3"]
        ;
        $input.css('color', 'yellow');
        changed = 1;
    }
});
于 2013-05-17T07:57:21.073 回答