0

我有一个包含jobs. 根据 a 的状态,job该作业会有某些按钮。为了让我的应用程序感觉更像一个原生应用程序,当其中一个作业的状态发生变化时,我使用 javascript 添加一个新的 html 按钮而不刷新页面。那个新添加的 html 按钮有一个类,其中绑定了一个 javascript 事件。但是每当我单击该按钮时,应该触发的事件永远不会消失。下面是一些例子:

刷新页面时创建的正常工作按钮

<div id="user_completed<%= i %>">
          <% if !is_runner?(@user) && job.status == 'assigned' %>
            <div class="row job-buttons" id="user_completed_button_row<%= i %>">
              <div class="small-6 columns">
                <div class="button small success radius user_completed_button" data-job-id="<%= i %>">job completed</div>
              </div>
            </div>
          <% end %>
        </div>

使用 javascript 添加的按钮

        var user_completed = '<div class="row job-buttons" id="user_completed_button_row' + id + '">' +
                                '<div class="small-6 columns">' +
                                    '<div class="button small success radius user_completed_button" data-job-id="' + id + '">job completed</div>' +
                                '</div>' +
                              '</div>';
        var user_completed_div = "#user_completed" + id;
        $(user_completed_div).html(user_completed);

这两个按钮应该是等效的。第一个按钮在刷新页面时作业处于“已完成”状态时创建,第二个按钮在作业处于“已完成”状态且页面未刷新时创建。这两个按钮应该具有完全相同的 HTML。

现在,当单击第一个按钮时,javascript 事件会顺利关闭,但是当单击第二个按钮时,javascript 事件根本不会触发。我不断检查 chrome 开发人员工具,它们似乎具有完全相同的 HTML。

这是我试图触发的事件。

  $('.user_completed_button').click(function(e) {
    var id = $(this).data('job-id');
    var url = "/jobs/" + id;
    $.ajax({
      type: "PUT",
      url: url,
      data: {job: {status: "completed"}},
      async: false, 
    });
  });

旁注:我正在使用 javascript 插件推送器以及 turbolinks。我不知道这是否会有所作为,只是想提一下。

4

3 回答 3

1

要处理动态创建的 DOM 对象的事件,您应该使用 jQueryon方法。像这样的东西

 $('.user_completed_button').on('click', function(event) { ... })

更多文档在这里:http ://api.jquery.com/on/

于 2013-07-28T01:53:16.710 回答
1

似乎您可能在元素出现在页面上之前绑定了点击处理程序,而 jQuery 只会在绑定发生时绑定到列表中的元素。

为确保您可以获得动态创建的元素,请将侦听器添加到父对象并on按照建议使用(或者delegate如果您有较旧的 jQuery)

$('#user_completed_holder_or_whatnot').on('click', '.user_completed_button', function(e) {
    var id = $(this).data('job-id');
    var url = "/jobs/" + id;
    $.ajax({
        type: "PUT",
        url: url,
        data: {job: {status: "completed"}},
        async: false, 
    });
});

这表示对于持有者('#user_completed_holder_or_whatnot')的任何点击,如果点击的目标与为第二个参数('.user_completed_button')传递的选择器匹配,则运行句柄方法。

编辑:您也可以在动态创建元素后重新绑定,但这会增加潜在的性能开销或使您的代码混乱。

于 2013-07-28T02:00:59.153 回答
0

将侦听器绑定到,document以便稍后可以添加按钮:

$(document).on('click', '.user_completed_button', function(e) {
  var id = $(this).data('job-id');
  var url = "/jobs/" + id;
  $.ajax({
    type: "PUT",
    url: url,
    data: {job: {status: "completed"}},
    async: false, 
  });
});

这相当于 jQuery 的弃用/删除live功能。

于 2013-07-28T02:23:28.553 回答