jQuery单击工作一次,而不是两次
jQuery Click Working Once, not Twice
在函数的作用域中,我加载HTML以通过AJAX在Bootstrap模式中显示。AJAX加载是昂贵的,我想缓存它加载的内容。但是,HTML中表的行可以动态更改,并且需要绑定到这些行的单击侦听器。
除了发布一些代码,我不知道如何最好地解释这种情况。
Fiddle:http://jsfiddle.net/vvc1j1eh/1/
因此,最大的问题是,为什么第一次加载点击在第一次就可以工作,而在我尝试重复使用缓存内容之后就不能了?还有为什么第二次加载作用域每次都会点击工作?
编辑:更好地解释问题
加载页面,然后单击"加载"以显示对话框。如果单击某一行,则会弹出一个警告,其中包含您单击的行。单击对话框之外的任何位置将其隐藏,然后再次单击"加载"。这一次,当您单击行时,不会弹出警报消息。
如果对"使用右侧作用域加载"按钮执行完全相同的过程,则在第二次显示对话框时单击行时仍会收到警报。
委派:
很难在示例中进行解释,但内容"文档"页面也是通过AJAX与多个页面一起动态加载的。当用户浏览Web应用程序时,会显示和隐藏这些多个页面,所以我不能只将全局侦听器绑定到文档。
这将是我在尝试授权时所做的最接近的事情:
var $data = expensiveAjaxLoad();
$data.on('click', 'tbody td', function() {
alert($(this).html());
});
$('#load').click(function() {
addRowsAndListeners($data);
$('#content').html($data);
$('#modal').modal('show');
});
它仍然没有回答的大问题,这就是为什么事件第二次不绑定?它们第一次绑定,在我进行调试时,作用域变量$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/
您需要对文档使用事件委派,因为存在动态创建的元素。同时移动文档就绪中的点击事件绑定,而不是函数addRowsAndListeners()
工作示例
$(document).on('click','tbody td',function() {
alert($(this).html());
});
更新:使用您的原始代码,将其委托给内容(表或模型体的容器),因为您的表也是动态
$("#content").on('click', 'tbody tr', function(e) {
e.preventDefault();
var $this = $(this);
if ($this.hasClass('selectable')) {
$this.toggleClass('success');
}
});
更新的fiddle:
我能够通过更改$('#load').click()
:JSFiddle DEMO来实现您想要的功能
$('#load').on("click", function() { //changed to on("click")
addRowsAndListeners($data);
$('#content').html($data);
$('#modal').modal('show');
//remove the on("click") and set up a new on("click") to just show the modal
$('#load').off("click").on("click", function() {
$('#modal').modal('show');
//you could add additional logic in here if you need to conditionally redo the ajax call
});
});
因为您正在添加行,jQuery没有意识到它们。您需要委托点击事件-
$(document).on('click', 'tbody td', function() {
alert($(this).html());
});
- 单击仅在第二次单击后有效
- 删除确认对话框在第一次单击时不起作用
- 在Rails中第一次单击后禁用链接,Coffeescription
- 在没有焦点的情况下捕获画布上的第一次单击事件
- Javascript onclick事件在第一次单击时未启动
- 只要用户将鼠标悬停在jQuery中的某个元素上,就可以执行多次单击
- 在单击事件中,第一次单击时激发代码一次,其余代码在所有单击时运行
- 无法在第一次单击时禁用链接,并在动画完成后重新启用
- 更改类名后,将第二次单击事件附加到元素
- 防止默认,直到连续两次单击
- 让窗口在一次单击触发两个页面重定向后保持焦点
- 奇怪的是,在第二次单击切换隐藏/显示按钮而不是第一次单击后,有两行有效
- 向同一按钮添加两次单击事件只能工作一次
- JQuery切换问题,需要两次单击
- jQuery完成的多部分表单需要两次单击才能识别.submit()和.click()事件处理程序
- 使用$(“[property=value]”).click(),我希望两次单击之间有一个延迟
- SVG元素中的Onclick需要初始的两次单击
- 要使用AngularJS修改html元素,必须点击两次单选按钮
- .change() 处理程序制作表单需要两次点击才能提交
- Javascript确认对话框出现两次;单击Element后返回