JQuery 事件委派混淆



我正在尝试创建一个点击事件侦听器,该侦听器侦听最近创建的HTML事件。整个选择器的事情让我感到困惑。这是我的代码:

var counter = 0;
$("#button").click(function() {
$(".slick").last().after("<div class='box'></div><div class='slick'></div>")
});
// With on():
$(".slick").on("click", function() {
$(".box").css("background-color", "blue");
});
.box {
background-color: red;
padding: 3px;
margin: 4px;
height: 20px;
width: 60px;
}
.slick {
background-color: #B2B2B2;
padding: 3px;
margin: 4px;
height: 10px;
width: 40px;
}
#button, #button1 {
background-color: #BCBCBC;
padding: 3px;
width: 90px;
margin: 7px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box"></div>
<div class="slick"></div>
<div class="box"></div>
<div class="slick"></div>
<div id="button">New Tab</div>

正如您在此处看到的,"新建选项卡"按钮添加了两个与以前完全相同的新元素。唯一的问题是,当我单击新生成的元素的.slick元素时,背景颜色不会像前两个.slick那样更改。

我不想把元素放在彼此里面。它们的树顺序应该保持不变。

那是因为$(".slick").on("click", function() {...});功能上与$(".slick").click(...)相同。请记住,事件绑定是在运行时完成的,这意味着新添加的.slick元素没有绑定 click 事件。为了确保从新添加的元素中捕获点击事件,您必须依靠事件冒泡。

换句话说,您希望在运行时存在的父元素级别侦听从任何.slick元素冒泡的 click 事件。一个示例是文档对象:

$(document).on("click", ".slick", function() {
$(".box").css("background-color", "blue");
});

上面的这段代码基本上是这样做的:它指示document对象侦听从任何具有slick类的子元素发起/冒泡的 click 事件。由于文档对象在运行时已经存在,这意味着无论在什么时候添加并单击新的.slick元素,都会触发回调。

理想情况下,由于性能问题,您不希望将其绑定到document对象。将其绑定到运行时可用的最接近的父级也可以正常工作。假设所有.slick元素都添加到运行时标记中存在的名为<div class="slick-wrapper">的父元素中,那么使用$('.slick-wrapper').on('click', '.slick', function() {...});也可以使用。

概念验证:

var counter = 0;
$("#button").click(function() {
$(".slick").last().after("<div class='box'></div><div class='slick'></div>")
});
$(document).on("click", ".slick", function() {
$(".box").css("background-color", "blue");
});
.box {
background-color: red;
padding: 3px;
margin: 4px;
height: 20px;
width: 60px;
}
.slick {
background-color: #B2B2B2;
padding: 3px;
margin: 4px;
height: 10px;
width: 40px;
}
#button, #button1 {
background-color: #BCBCBC;
padding: 3px;
width: 90px;
margin: 7px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box"></div>
<div class="slick"></div>
<div class="box"></div>
<div class="slick"></div>
<div id="button">New Tab</div>

您可以添加样式标签以影响将来创建的元素。像这样:

var counter = 0;
$("#button").click(function() {
$(".slick").last().after("<div class='box'></div><div class='slick'></div>")
});
// With on():
$(".slick").on("click", function() {
$('<style>.box { background-color: blue !important; }</style>').appendTo('head'); 
});
.box {
background-color: red;
padding: 3px;
margin: 4px;
height: 20px;
width: 60px;
}
.slick {
background-color: #B2B2B2;
padding: 3px;
margin: 4px;
height: 10px;
width: 40px;
}
#button, #button1 {
background-color: #BCBCBC;
padding: 3px;
width: 90px;
margin: 7px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box"></div>
<div class="slick"></div>
<div class="box"></div>
<div class="slick"></div>
<div id="button">New Tab</div>

如果您单击"新选项卡"按钮,js 添加新框和光滑,前 2 个光滑将更改所有框的颜色,但较新的不会。这样做的原因,您首先将事件添加到光滑元素中,然后创建一个新元素。 此代码还将为新代码添加事件:

$("body").on("click", ".slick", function() {
$(".box").css("background-color", "blue");
});

最新更新