首先,我是jQuery的新手。创建一个简单的程序并不是火箭科学,但以下代码的效果对我来说没有任何意义。我的意图是在点击一个带有“.button”类的元素之后,应该向该元素添加一个新类。否则 - 点击其他地方 - 应该删除当前的新类。不幸的是,即使条件为真,也会执行else中的代码。我的想法存在哪些缺陷?你能解决这个问题吗?
$(function() {
$("*").click(function() {
var ret = $(this).hasClass("button");
if (ret) {
$(".button").addClass("newclass");
} else {
$(".button").removeClass("newclass");
}
});
$("form").on("submit", function() {
return false;
})
});
.newclass {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<form method="get" action="">
<input type="text" name="">
<input type="submit" name="" class="button">
</form>
答案 0 :(得分:10)
click
个事件冒泡从被点击的元素到文档,传递到途中的所有元素。
那么当您单击按钮时会发生的情况是,在添加类时(因为按钮具有类button
),点击会弹到form
(没有),然后到body
(不是)然后到html
(没有)。您的处理程序在每个级别都被调用,因为您已将它附加到所有元素,因此最后一个(html
)获胜。
因此,对代码的最小更改是在处理点击时停止传播(告诉事件停止冒泡):
$("*").click(function(e) {
// Note --------------^
e.stopPropagation(); // <===
var ret = $(this).hasClass("button");
if (ret) {
$(".button").addClass("newclass");
} else {
$(".button").removeClass("newclass");
}
});
示例:
$(function() {
$("*").click(function(e) {
e.stopPropagation();
var ret = $(this).hasClass("button");
if (ret) {
$(".button").addClass("newclass");
} else {
$(".button").removeClass("newclass");
}
});
$("form").on("submit", function() {
return false;
})
});
.newclass {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<form method="get" action="">
<input type="text" name="">
<input type="submit" name="" class="button">
</form>
但是,我会彻底改变你的做法。我没有在DOM中的每个元素上设置处理程序,而只是附加到document
,然后检查e.target
:
$(document).click(function(e) {
// ^^^^^^ --- note --------^
var ret = $(e.target).hasClass("button");
// Note ------^^^^^^^^
if (ret) {
$(".button").addClass("newclass");
} else {
$(".button").removeClass("newclass");
}
});
等待点击冒泡到document.body
,然后查看它从哪里冒出来(e.target
)。
示例:
$(function() {
$(document).click(function(e) {
// Note ------------------------^
var ret = $(e.target).hasClass("button");
if (ret) {
$(".button").addClass("newclass");
} else {
$(".button").removeClass("newclass");
}
});
$("form").on("submit", function() {
return false;
})
});
.newclass {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<form method="get" action="">
<input type="text" name="">
<input type="submit" name="" class="button">
</form>
如果您使用的元素可能包含子元素(例如button
而不是input
),那么您可能会遇到点击可能来自孩子的情况或后代。在这种情况下,您可以使用closest
来确定点击是否通过.button
元素传递到document
:
var ret = $(e.target).closest(".button").length;
if (ret) {
// The element clicked or an ancestor of it has the class...
(我们依赖的事实是0
是假的,但所有其他非NaN
数字都不是。)
示例:
$(function() {
$(document).click(function(e) {
// Note ------------------------^
var ret = $(e.target).closest(".button").length;
if (ret) {
$(".button").addClass("newclass");
} else {
$(".button").removeClass("newclass");
}
});
$("form").on("submit", function() {
return false;
})
});
.newclass {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<form method="get" action="">
<input type="text" name="">
<button class="button">
Direct <strong>Child</strong>
</button>
</form>
答案 1 :(得分:-1)
首先在表单中添加一个选择器,如下所示:
<form method="get" action="" class="simpleForm">
<input type="text" name="">
<input type="submit" name="" class="button">
</form>
监听任何点击事件的下一个目标,检查点击是否仅在输入上发生。
$('.simpleForm').unbind('click').bind('click', function(e) {
if($(this).hasClass('button') && e.target.tagName === 'input') {
$(this).addClass("newclass");
} else {
$(this).removeClass("newclass");
}
});