停止父元素的 onclick 传播但允许下拉菜单 open/close 和 Bootstrap 下拉菜单的菜单项事件?
Stop parent element onclick propagation but allow dropdown open/close and menu item events for Bootstrap dropdown?
我有一个带有 select
选项的 jQuery DataTables
table(单击时选择行)。我遇到的问题是单击下拉按钮和下拉菜单项导致选择基础行。 我怎样才能防止底层的 td
/tr
/DataTable select
单击事件,但允许 dropdown
及其菜单项(li a
子项) 点击事件?
<table id="datatable">
<tr>
<td>
<div class="dropdown">
<button type="button" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-caret-down"></i>
</button>
<ul class="dropdown-menu">
<li><a href="#" class="action">Action</a></li>
</ul>
</div>
</td>
</tr>
<tr>
<td>
<div class="dropdown">
<button type="button" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-caret-down"></i>
</button>
<ul class="dropdown-menu">
<li><a href="#" class="action">Action</a></li>
</ul>
</div>
</td>
</tr>
</table>
<script>
$("#datatable").DataTable({ select: true });
</script>
我试过使用 e.stopPropagation()
但这 阻止了下拉菜单显示 :
<script>
$("#dataTable tbody").on("click", "button", function (e) {
e.stopPropagation(); // this prevents dropdown menu from showing
});
</script>
我也尝试过手动切换下拉菜单,但这 引入了奇怪的下拉行为(例如,单击一行的下拉按钮显示其下拉菜单,但没有隐藏任何其他行'已打开的下拉菜单):
<script>
$("#dataTable tbody").on("click", "button", function (e) {
$(this).closest("div.dropdown").toggleClass("open"); // weird effects
// or:
$(this).closest("div.dropdown").find("ul.dropdown-menu").toggle(); // weird effects
e.stopPropagation();
});
</script>
我也尝试了 dropdown("toggle")
,但是虽然这解决了上述奇怪的行为,但它仍然 阻止了菜单项的点击事件 :
<script>
$("#dataTable tbody").on("click", "button", function (e) {
// no weird behavior, but now menu item click events are disabled
$(this).closest("div.dropdown").find("ul.dropdown-menu").dropdown("toggle");
e.stopPropagation();
});
</script>
原来 jQuery DataTables
为这种情况提供了事件处理程序 user-select.dt
。我能够获得正常工作所需的所有功能:
<script>
$("#datatable").DataTable({
select: true
}).on("user-select.dt", function (e, dt, type, cell, originalEvent) {
var $elem = $(originalEvent.target); // get element clicked on
var tag = $elem[0].nodeName.toLowerCase(); // get element's tag name
if (!$elem.closest("div.dropdown").length) {
return; // ignore any element not in the dropdown
}
if (tag === "i" || tag === "a" || tag === "button") {
return false; // cancel the select event for the row
}
});
</script>
我有一个带有 select
选项的 jQuery DataTables
table(单击时选择行)。我遇到的问题是单击下拉按钮和下拉菜单项导致选择基础行。 我怎样才能防止底层的 td
/tr
/DataTable select
单击事件,但允许 dropdown
及其菜单项(li a
子项) 点击事件?
<table id="datatable">
<tr>
<td>
<div class="dropdown">
<button type="button" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-caret-down"></i>
</button>
<ul class="dropdown-menu">
<li><a href="#" class="action">Action</a></li>
</ul>
</div>
</td>
</tr>
<tr>
<td>
<div class="dropdown">
<button type="button" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-caret-down"></i>
</button>
<ul class="dropdown-menu">
<li><a href="#" class="action">Action</a></li>
</ul>
</div>
</td>
</tr>
</table>
<script>
$("#datatable").DataTable({ select: true });
</script>
我试过使用 e.stopPropagation()
但这 阻止了下拉菜单显示 :
<script>
$("#dataTable tbody").on("click", "button", function (e) {
e.stopPropagation(); // this prevents dropdown menu from showing
});
</script>
我也尝试过手动切换下拉菜单,但这 引入了奇怪的下拉行为(例如,单击一行的下拉按钮显示其下拉菜单,但没有隐藏任何其他行'已打开的下拉菜单):
<script>
$("#dataTable tbody").on("click", "button", function (e) {
$(this).closest("div.dropdown").toggleClass("open"); // weird effects
// or:
$(this).closest("div.dropdown").find("ul.dropdown-menu").toggle(); // weird effects
e.stopPropagation();
});
</script>
我也尝试了 dropdown("toggle")
,但是虽然这解决了上述奇怪的行为,但它仍然 阻止了菜单项的点击事件 :
<script>
$("#dataTable tbody").on("click", "button", function (e) {
// no weird behavior, but now menu item click events are disabled
$(this).closest("div.dropdown").find("ul.dropdown-menu").dropdown("toggle");
e.stopPropagation();
});
</script>
原来 jQuery DataTables
为这种情况提供了事件处理程序 user-select.dt
。我能够获得正常工作所需的所有功能:
<script>
$("#datatable").DataTable({
select: true
}).on("user-select.dt", function (e, dt, type, cell, originalEvent) {
var $elem = $(originalEvent.target); // get element clicked on
var tag = $elem[0].nodeName.toLowerCase(); // get element's tag name
if (!$elem.closest("div.dropdown").length) {
return; // ignore any element not in the dropdown
}
if (tag === "i" || tag === "a" || tag === "button") {
return false; // cancel the select event for the row
}
});
</script>