与静态祖先的事件绑定导致每个点击事件被触发
Event binding with Static Ancestors leads to every click event being triggered
我创建了一个小型测试应用程序,应该允许用户创建:
- 创建列表元素
- 删除列表元素
- 创建列表
- 删除列表
我了解到动态添加的元素不会绑定到它们的事件(基于此:Event binding on dynamically created elements?)所以我尝试将事件附加到单个静态祖先。不幸的是,这会导致仅在按下一个按钮时触发每个单击事件。
<head>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<title>Test Page</title>
</head>
<body>
<div id="container">
<div class="listContainer">
<ol>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
</ol>
<button class="btnAddListElement">+Add List Item</button>
<button class="btnDeleteList">Delete List</button>
</div>
<button class="btnAddList">+Add List</button>
</div>
</body>
<script>
var btnDeleteListItem = $(".btnDeleteListItem");
var btnAddListElement = $(".btnAddListElement");
var btnDeleteList = $(".btnDeleteList");
var btnAddList = $(".btnAddList");
var container = $("#container");
container.on("click",btnDeleteListItem, function (e) {
$(this).parent().remove();
console.log("list item deleted");
});
container.on("click",btnAddListElement, function (e) {
var html = '<li> Just added <button class="btnDeleteListItem">Delete</button></li>';
$("ol").append(html);
console.log("list item added");
});
container.on("click",btnDeleteList, function (e) {
$(this).parent().remove();
console.log("list deleted");
});
btnAddList.on("click", function(e){
var html = '<div class="listContainer"><ol><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li></ol><button class="btnAddListElement">+Add List Item</button><button class="btnDeleteList">Delete List</button></div>';
$(html).insertBefore($(this));
console.log("list added");
});
</script>
</html>`
有没有办法隔离点击事件?
问题是因为,虽然您使用的是委托事件处理程序,但您只是在 DOM 加载时选择元素。要解决此问题,请将选择器参数作为字符串传递给 on()
。这样,选择器将在 click
事件通过 #container
时匹配,而不仅仅是针对特定元素实例。
另请注意,您需要在与 .btnAddListElement
按钮相关的 ol
上仅 调用 单击,否则您最终会向每个列表添加一个新的 li
。为此,请将 $('ol')
更改为 $(this).prev('ol')
。
var $container = $("#container");
$container.on("click", ".btnDeleteListItem", function(e) {
$(this).parent().remove();
console.log("list item deleted");
});
$container.on("click", '.btnAddListElement', function(e) {
var html = '<li> Just added <button class="btnDeleteListItem">Delete</button></li>';
$(this).prev("ol").append(html);
console.log("list item added");
});
$container.on("click", '.btnDeleteList', function(e) {
$(this).parent().remove();
console.log("list deleted");
});
$container.on('click', '.btnAddList', function(e) {
var html = '<div class="listContainer"><ol><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li></ol><button class="btnAddListElement">+Add List Item</button><button class="btnDeleteList">Delete List</button></div>';
$(html).insertBefore($(this));
console.log("list added");
});
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<div id="container">
<div class="listContainer">
<ol>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
</ol>
<button class="btnAddListElement">+Add List Item</button>
<button class="btnDeleteList">Delete List</button>
</div>
<button class="btnAddList">+Add List</button>
</div>
我创建了一个小型测试应用程序,应该允许用户创建:
- 创建列表元素
- 删除列表元素
- 创建列表
- 删除列表
我了解到动态添加的元素不会绑定到它们的事件(基于此:Event binding on dynamically created elements?)所以我尝试将事件附加到单个静态祖先。不幸的是,这会导致仅在按下一个按钮时触发每个单击事件。
<head>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<title>Test Page</title>
</head>
<body>
<div id="container">
<div class="listContainer">
<ol>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
</ol>
<button class="btnAddListElement">+Add List Item</button>
<button class="btnDeleteList">Delete List</button>
</div>
<button class="btnAddList">+Add List</button>
</div>
</body>
<script>
var btnDeleteListItem = $(".btnDeleteListItem");
var btnAddListElement = $(".btnAddListElement");
var btnDeleteList = $(".btnDeleteList");
var btnAddList = $(".btnAddList");
var container = $("#container");
container.on("click",btnDeleteListItem, function (e) {
$(this).parent().remove();
console.log("list item deleted");
});
container.on("click",btnAddListElement, function (e) {
var html = '<li> Just added <button class="btnDeleteListItem">Delete</button></li>';
$("ol").append(html);
console.log("list item added");
});
container.on("click",btnDeleteList, function (e) {
$(this).parent().remove();
console.log("list deleted");
});
btnAddList.on("click", function(e){
var html = '<div class="listContainer"><ol><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li></ol><button class="btnAddListElement">+Add List Item</button><button class="btnDeleteList">Delete List</button></div>';
$(html).insertBefore($(this));
console.log("list added");
});
</script>
</html>`
有没有办法隔离点击事件?
问题是因为,虽然您使用的是委托事件处理程序,但您只是在 DOM 加载时选择元素。要解决此问题,请将选择器参数作为字符串传递给 on()
。这样,选择器将在 click
事件通过 #container
时匹配,而不仅仅是针对特定元素实例。
另请注意,您需要在与 .btnAddListElement
按钮相关的 ol
上仅 调用 单击,否则您最终会向每个列表添加一个新的 li
。为此,请将 $('ol')
更改为 $(this).prev('ol')
。
var $container = $("#container");
$container.on("click", ".btnDeleteListItem", function(e) {
$(this).parent().remove();
console.log("list item deleted");
});
$container.on("click", '.btnAddListElement', function(e) {
var html = '<li> Just added <button class="btnDeleteListItem">Delete</button></li>';
$(this).prev("ol").append(html);
console.log("list item added");
});
$container.on("click", '.btnDeleteList', function(e) {
$(this).parent().remove();
console.log("list deleted");
});
$container.on('click', '.btnAddList', function(e) {
var html = '<div class="listContainer"><ol><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li></ol><button class="btnAddListElement">+Add List Item</button><button class="btnDeleteList">Delete List</button></div>';
$(html).insertBefore($(this));
console.log("list added");
});
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<div id="container">
<div class="listContainer">
<ol>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
</ol>
<button class="btnAddListElement">+Add List Item</button>
<button class="btnDeleteList">Delete List</button>
</div>
<button class="btnAddList">+Add List</button>
</div>