与attr()方法一起使用时的jQuery clone()问题

时间:2011-03-28 23:29:40

标签: javascript jquery jquery-ui dom javascript-events

我使用jQuery clone()方法克隆表行,然后使用attr()方法更改某些字段的名称/ id。这一切都运行良好,如果我使用“查看生成的源”,名称/ ID正在设置正确,但是当生成的内容触发JavaScript事件时,它会触发它,就像它是父元素一样。例如,我有一个名为/ id'strst1'的元素,它应该触发自动完成方法(基于它是'slast'类的一部分)并且工作正常。不幸的是,当我在生成的行中单击相同的元素时(在这种情况下,元素id / name是'slast2'),它会触发自动完成方法,但就好像它是从父元素'slast1'触发的。我似乎无法找到解决这个问题的方法,并且认为这可能是使用clone()方法的限制,但我希望我只是缺少一些东西。

function fnAddRow(iRow)
{
  var iNewRow = iRow+1;
  $("#tblAuthors tr:last").clone(true).insertAfter("#tblAuthors tr:last");
  $("#tblAuthors tr:last #slast"+iRow).attr("name", "slast"+iNewRow);
  $("#tblAuthors tr:last #slast"+iRow).attr("id", "slast"+iNewRow);
  $("#slast"+iNewRow).val("");
}

上面的代码克隆了表行,并改变了我之前提到的属性。下面的代码是由'slastX'元素中的'keydown'事件触发的,但无论出于何种原因,生成的元素都被视为父元素。

  $(function()
  {
    var aEmps = 
    [
<?php
echo $sEmps;
?>    
    ];

    $(".slast").bind( "keydown", function( event ) {
      if ( event.keyCode === $.ui.keyCode.TAB &&
          $( this ).data( "autocomplete" ).menu.active ) 
          { event.preventDefault();}
    })
    .autocomplete({
      source: aEmps,
      close: function(event, ui)
      {
        // Split return value and store in array
        var aName = this.value.split(", ");
        // Get row #
        var iRow = this.name[this.name.length-1];
        // Populate values        
        $("#slast"+iRow).val(aName[0]);
        $("#sfirst"+iRow).val(aName[1]);
        $("#smi"+iRow).val(aName[2]);
      }
    });
  });

正如你所看到的那样,自动完成方法应该由任何具有“slast”类的东西触发,但由于我无法弄清楚$(this)总是=父('slast1')而不是'slast2'或任何其他生成的内容。

3 个答案:

答案 0 :(得分:2)

使用live代替bind,这可以为您解决问题。

答案 1 :(得分:1)

当您使用.clone(true)时,您正在处理所有 data()绑定到该元素的所有事件。这导致了你的问题。

如果您将事件绑定切换为使用.delegate()(或.live()),您应该能够解决触发事件的问题。

var autoCompleteOptions = {
  source: aEmps,
  close: function(event, ui)
  {
    // Split return value and store in array
    var aName = this.value.split(", ");
    // Get row #
    var iRow = this.name[this.name.length-1];
    // Populate values        
    $("#slast"+iRow).val(aName[0]);
    $("#sfirst"+iRow).val(aName[1]);
    $("#smi"+iRow).val(aName[2]);
  }
};

$("#tblAuthors").delegate("tr .slast", "keydown", function(event){
    if ( event.keyCode === $.ui.keyCode.TAB && 
          $( this ).data( "autocomplete" ).menu.active ) { 
     event.preventDefault();
   }
}).autocomplete(autoCompleteOptions);


function fnAddRow(iRow)
{
  //....stuff.....
  $("#tblAuthors tr:last #slast"+iRow).autocomplete(autoCompleteOptions);
  //....stuff.....
}

使用委托,您将事件绑定到$("#tblAuthors"),而不是直接绑定.slast

同样在旁注上,使用delegeate可能会获得与此answer相关的一些性能。

更新:Mark和我在解决方案上来回了很多,这是最终的代码:http://jsfiddle.net/niczak/HjCMh/1/

答案 2 :(得分:0)

在查看哪些事件处理程序绑定到各种元素时,您可能会发现一个有用的工具Visual Event,它可以作为书签使用,我觉得它有时非常有用。

在您的情况下,它应该让您看到哪些处理程序绑定到克隆的行(如果有的话)。