1

フォームを生成するこの PHP スクリプトがあります。

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>";
}

私が必要とするのは、特定の行の入力フィールドのテキストを、その行の要素が変更されるたびに一度だけ更新することです。これまでのところ、これを思いつきました (便宜上、動作を簡単に確認するために css('color', 'yellow') を使用します)。ただし、変更された要素は 1 回だけ更新されます (changed が 1 に設定されているため、行ごとに新しい「変更済み」が必要ですが、行がいくつになるかわかりません)。

 $( 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');

      }
    });

  });

});

方法 2: 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: 1 つの方法を使用する

別のフィドル

one メソッドは、イベントを 1 回処理します。

またはの代わりに使用するビリオネカンからの素晴らしいアドバイスを含む更新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)

そのはず

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

clicked何のためにあるのかはわかりませんchangedが、ifステートメントは現在の値を 0 に設定clickedしており、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 に答える