我有以下代码按预期工作:
第一种方法
$('ul').on('click', function(e) {
$(this).append('<li>foo</li>');
})
.on('click', 'li', function(e) {
e.stopPropagation();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
我很酷,这就是我想要的行为。使用这种方法看起来子弹点不是li元素的一部分,因为在子弹点上执行的任何点击都不会通过第二个函数。
我提出问题之后我认为我可以稍微重构一下javascript代码,在第一次调用中将“:not(li)”选择器作为参数传递给它。
第二种方法:
$('ul').on('click', ":not(li)", function(e) {
$(this).append('<li>foo</li>');
});
但事实证明行为不同,我不明白为什么在点击项目符号后不添加li元素。
第二种方法看起来更清晰,但与我们在第一种方法中所看到的相反,就像子弹点是li元素的一部分。
- 为什么第二种方法表现不同?
答案 0 :(得分:1)
这是因为ul :not(li)
会选择ul
不是li
元素的任何后代。
由于您的ul
元素只包含li
元素,因此事件永远不会被触发。但是,如果li
元素包含span
元素,则单击span
元素时会触发该事件,但这不是所需的结果。
在点击li
元素时,我只是建议检查this
是否等于e.target
,而不是压制事件。这与你的第一个例子类似。
$('ul').on('click', function(e) {
if (this === e.target) {
$(this).append('<li>foo</li>');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>