简体   繁体   English

jquery 和 console.log 问题

[英]jquery and console.log issue

I have multiple toggle switches on my page.我的页面上有多个切换开关。 They are from bootstrap.它们来自引导程序。 Everything works as expected, however, I have come across an error within the javascript console.一切都按预期工作,但是,我在 javascript 控制台中遇到了错误。 Or warning should I say.或者我应该说警告。 When I have only one toggle on the page and I click it it will print one line in the console, which is as expected.当我在页面上只有一个切换并单击它时,它将在控制台中打印一行,这是预期的。 When I dynamically add another toggle, using the script below, when I click on the last added toggle it will print again only one line, but every other will print multiple lines.当我使用下面的脚本动态添加另一个切换时,当我单击最后一个添加的切换时,它将再次仅打印一行,但每隔一行将打印多行。

Ie when I have 5 toggles and click on the last one, it will print one line in the console.即当我有 5 个切换并单击最后一个时,它将在控制台中打印一行。 When I click on 4th it will print two lines and so on.当我点击 4th 时,它将打印两行,依此类推。 When I click on the 1st it will print 5 lines.当我单击第一个时,它将打印 5 行。

If I have multiple toggles set from beginning without adding them dynamically it works fine.如果我从一开始就设置了多个切换而不动态添加它们,它就可以正常工作。

Any ideas?有任何想法吗?

<script>

$(window).ready(function() {

  $("[data-toggle='toggle']").bootstrapToggle({
    on: 'On',
    off: 'Off',
    size: 'small'
  });

  $('#addRow').on('click', function(event) {
    event.preventDefault();
    var rowID =+ $('table tr:last').attr('id')+1;

      $('#users').find('tbody').append([
      "<tr class='userRow' id='"+rowID+"'>",
        "<td>"+rowID+"</td>",
        "<td><input type='text' class='form-control'></td>",
        "<td><input type='text' class='form-control'></td>",
        "<td><input type='text' class='form-control'></td>",
        "<td><input type='checkbox' class='toggle-voicemail' data-toggle='toggle'></td>",
        "<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>",
        "<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>",
        "<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>",
        "<td><a class='deleteRow btn btn-danger' value='"+rowID+"'>Delete</a></td>",
      "</tr>"
      ].join(''));

      $("[data-toggle='toggle']").bootstrapToggle('destroy');
      $("[data-toggle='toggle']").bootstrapToggle({ size: 'small' });

    $('.toggle-voicemail').on('change', function(event) {
    event.preventDefault();
    var id = $(this).parents('tr').attr('id');
    console.log("Voicemail for userID:"+id);
   });

});

    $('.toggle-voicemail').on('change', function(event) {
    event.preventDefault();
    var id = $(this).parents('tr').attr('id');
    console.log("Voicemail for userID:"+id);

    });

    $('#users').on('click', 'a.deleteRow', function(event) {
    event.preventDefault();
    //var id = $(this).find('a').attr('value');
    $(this).parents('tr').remove();

    });
});
</script>

HTML HTML

<div class="box box-primary" id="usersDetails" style="">
  <div class="box-header with-border">
    <h3 class="box-title">Users</h3>
  </div>
  <div class="box-body">
    <table class="table table-condensed text-center" id="users">
      <thead>
        <tr>
          <th>ID</th>
          <th width="300">Username</th>
          <th>Phone</th>
          <th></th>
          <th>Voicemail</th>
          <th width="50">RG 1</th>
          <th width="50">RG 2</th>
          <th width="50">RG 3</th>
          <th width="100"></th>
        </tr>
      </thead>

    <tbody>

      <tr class='userRow' id='1'>
        <td>1</td>
        <td><input type='text' class='form-control'></td>
        <td><input type='text' class='form-control'></td>
        <td><input type='text' class='form-control'></td>
        <td><input type='checkbox' class='toggle-voicemail' data-toggle='toggle'></td>
        <td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>
        <td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>
        <td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>
        <td></td>
      </tr>



    </tbody>
  </table>
  <input type="button" id="addRow" value="Add another user" class="btn btn-success">
  </div>
</div>

You are adding the event function multiple times.您正在多次添加事件 function。 The solution to this is to make your function non-anonymous:解决方案是让您的 function 非匿名:

var myFunc = function(event) {
    event.preventDefault();
    //var id = $(this).find('a').attr('value');
    $(this).parents('tr').remove();
}

And then call.off to before calling.on to prevent multiple listeners然后 call.off 到之前 call.on 以防止多个监听器

$('.toggle-voicemail').off('change', myFunc);
$('.toggle-voicemail').on('change', myFunc);

You're binding this event inside of your "add row" functionality:您将此事件绑定在“添加行”功能中:

$('.toggle-voicemail').on('change', function(event) {

Which means every time you add a row, you're adding another binding to every matching .toggle-voicemail element on the page, including the ones which already have that event binding.这意味着每次添加一行时,都会为页面上每个匹配.toggle-voicemail元素添加另一个绑定,包括已经具有该事件绑定的元素。

Instead of re-binding when adding a row, create a delegated binding once when the page loads that handles dynamically added elements.添加行时不要重新绑定,而是在页面加载时创建一次委托绑定,以处理动态添加的元素。 Basically, do this outside of the "add row" functionality:基本上,在“添加行”功能之外执行此操作:

$(document).on('change', '.toggle-voicemail', function(event) {
    event.preventDefault();
    var id = $(this).parents('tr').attr('id');
    console.log("Voicemail for userID:"+id);
});

That is caused because every time you add a new toggle, you reattach the event listener to all of the existing toggles and not only for the newly created one.这是因为每次添加新切换时,都会将事件侦听器重新附加到所有现有切换,而不仅仅是新创建的切换。

You can make a let variable to store the newly generated toggle, and then instead of doing您可以制作一个let变量来存储新生成的切换,然后代替

$('.toggle-voicemail').on('change', function(event) { ...

you can do:你可以做:

$elem.on('change', function(event) { ...

It looks like your problem is that you are just adding event handlers and never removing them.看起来您的问题是您只是添加事件处理程序而从不删除它们。 So you need to only add an event handler to the newly-added element, or remove all event handlers (using .off() ),and then adding them again.因此,您只需向新添加的元素添加一个事件处理程序,或者删除所有事件处理程序(使用.off() ),然后再次添加它们。

I would opt for the former approach (adding an event listener to the new element only).我会选择前一种方法(仅向新元素添加事件侦听器)。

The best way to do this is the create the elements, then add all your event handlers (and whatever else you want to change about the element).最好的方法是创建元素,然后添加所有事件处理程序(以及您想要更改元素的任何其他内容)。 THEN append it to the DOM.然后 append 到 DOM。

so:所以:


// create the new row.
// reusing your `.join()` technique for ease of demo here.
var newRow = $("<tr class='userRow' id='"+rowID+"'>",
        "<td>"+rowID+"</td>",
        "<td><input type='text' class='form-control'></td>",
        "<td><input type='text' class='form-control'></td>",
        "<td><input type='text' class='form-control'></td>",
        "<td><input type='checkbox' class='toggle-voicemail' data-toggle='toggle'></td>",
        "<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>",
        "<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>",
        "<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>",
        "<td><a class='deleteRow btn btn-danger' value='"+rowID+"'>Delete</a></td>",
      "</tr>".join(''));

// toggle-ify the element.
newRow.find("[data-toggle='toggle']").bootstrapToggle({ size: 'small' });

newRow.find('.toggle-voicemail').on('change', function(event) {
    event.preventDefault();
    var id = $(this).parents('tr').attr('id');
    console.log("Voicemail for userID:"+id);
});

newRow.find('a.deleteRow').on('click', function(event) {
    event.preventDefault();
    //var id = $(this).find('a').attr('value');
    $(this).parents('tr').remove();
});

// append to table.
$('#users').find('tbody').append(newRow);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM