javascript - jQuery 点击工作一次,而不是两次

标签 javascript jquery twitter-bootstrap scope

在函数范围内,我正在加载 HTML 以通过 AJAX 在 Bootstrap 模态中显示。 AJAX 加载很昂贵,我想缓存它加载的内容。但是,HTML 中表格的行是动态变化的,需要绑定(bind)点击监听器。

除了发布一些代码,我不知道如何最好地解释这种情况。

fiddle :http://jsfiddle.net/vvc1j1eh/1/

所以最大的问题是,为什么第一次加载点击第一次有效,但在我尝试重新使用缓存内容后却无效?另外,为什么第二次加载范围点击每次都有效?

编辑:更好地解释问题

加载页面,然后单击“加载”以显示对话框。如果您单击一行,将弹出一个警告,其中包含您单击的行。单击对话框外的任意位置将其隐藏,然后再次单击“加载”。这一次,当您单击行时,不会弹出警告消息。

如果您对 Load With Right Scope 按钮执行完全相同的过程,您将在第二次显示对话框时单击行时仍会收到警报。

委派:

很难在示例中解释,但是内容“文档”页面也通过 AJAX 与多个页面一起动态加载。这些多个页面在用户浏览 web 应用程序时显示和隐藏,因此我不能只将全局监听器绑定(bind)到文档。

这将是我在尝试委派时所做的最接近的等价物:

var $data = expensiveAjaxLoad();
$data.on('click', 'tbody td', function() {
    alert($(this).html());
});
$('#load').click(function() {
    addRowsAndListeners($data);

    $('#content').html($data);
    $('#modal').modal('show');
});

它仍然没有回答大问题,即为什么事件不会第二次绑定(bind)?它们是第一次绑定(bind),在我调试时,范围变量 $data 似乎没有任何变化。

堆栈代码段:

$(document).ready(function() {
  //Scope of the function

  //$data works the first time, but additional row
  //clicks don't register events
  var $data = expensiveAjaxLoad();
  $('#load').click(function() {
    addRowsAndListeners($data);

    $('#content').html($data);
    $('#modal').modal('show');
  });

  //Why does this work?
  $('#load-scope').click(function() {
    var $better = expensiveAjaxLoad();
    addRowsAndListeners($better);

    $('#content').html($better);
    $('#modal').modal('show');
  });
});

function expensiveAjaxLoad() {    
  var html = [];
  html.push('<table><tbody>');
  html.push('</tbody></table>');
  return $(html.join(''));
}

function addRowsAndListeners($data) {
  var html = [];
  //Rows can vary, don't need to recreate the entire table
  for (var i = 0; i < 5; i++) {
    html.push('<tr><td>Row ');
    html.push((i + 1));
    html.push('</td></tr>');
  }
  $('tbody', $data).html(html.join(''));

  //Something here is not binding correctly
  $('tbody td', $data).click(function() {
    alert($(this).html());
  });
}
<!DOCTYPE html>
<html>
    <head>
        <title>Test</title>
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
    </head>
    <body>
        <div>
            <h1>Hello Alice</h1>
            <button id="load">Load</button>
            <button id="load-scope">Load With Right Scope</button>
        </div>
        <div id="modal" class="modal fade">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h4 class="modal-title">Modal Title</h4>
                    </div>
                    <div id="content" class="modal-body">
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

更新:

这是一个新的 Fiddle,其中包含我当前生产代码的最少数量。

http://jsfiddle.net/0vb2psv4/1/

最佳答案

您需要在文档上使用事件委托(delegate),因为有动态创建的元素。也将点击事件绑定(bind)移动到 document ready 而不是函数 addRowsAndListeners()

Working example

 $(document).on('click','tbody td',function() {
        alert($(this).html());
    });

更新:使用您的原始代码,将其委托(delegate)给内容(表格容器或模型主体),因为您的表格也是动态的

$("#content").on('click', 'tbody tr', function(e) {
        e.preventDefault();
            var $this = $(this);
            if ($this.hasClass('selectable')) {
                $this.toggleClass('success');
            }
        });

updated fiddle:

关于javascript - jQuery 点击工作一次,而不是两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25892990/

相关文章:

javascript - Leaflet JS map 和函数来选择新的数据层

javascript - Leaflet .locate 监视选项在更改选项卡 Ionic 3 后中断 .locate

javascript - 如何使用 HTML 上传图片并使用 JS 在网站上进行预览?

javascript - SVG:单击按钮后触发 animateTransform 上的单击事件

javascript - capybara 和恶作剧 'select' 文本输入

javascript - 我的 index.js 中没有任何 React 渲染

javascript - jQuery 将值字符串转换为数组

css - 未使用 Twitter Bootstrap 修复时居中导航栏内容?

html - 不能居中 Bootstrap 导航栏

javascript - Angular ui-bootstrap datepicker更改主题