在我的(live site)上,我使用'nice-select'库创建了一个select元素。这个select元素嵌套在一个下拉菜单中,该菜单有自己的JavaScript文件
function singleMenu(targetId, menuId, show = false) {
const targetElement = document.getElementById(targetId);
const menuElement = document.getElementById(menuId);
// Initial state
if (show) {
// show dropdown
menuElement.style.display = "block";
targetElement.classList.add("active");
} else {
// hide dropdown
menuElement.style.display = "none";
targetElement.classList.remove("active");
}
// Toggle menu visibility when target element is clicked
targetElement.addEventListener("click", () => {
show = !show;
if (show) {
// show dropdown
menuElement.style.display = "block";
targetElement.classList.add("active");
} else {
// hide dropdown
menuElement.style.display = "none";
targetElement.classList.remove("active");
}
});
// Close menu if clicked outside of container
document.addEventListener("click", (event) => {
if (!targetElement.contains(event.target)) {
show = false;
menuElement.style.display = "none";
targetElement.classList.remove("active");
}
});
// Prevent menu from closing when clicked inside the menu element
menuElement.addEventListener("click", function (event) {
event.stopPropagation();
});
// Calculate half of the targetElement width
const targetHalfWidth = targetElement.offsetWidth / 2;
// Set a CSS variable with the half width value
targetElement.style.setProperty(
"--target-half-width",
targetHalfWidth + "px"
);
}
字符串
目前,我面临着一个问题,选择元素在单击时无法打开,但在使用enter和up/down按钮时可以正常工作。
我怀疑这个问题可能与event.stopPropagation()函数有关,因为当我删除该行时,会添加select元素的'open'类(如inspect工具中所示)。但是,删除event.stopPropagation()行也会导致下拉菜单立即关闭。
我的目标是找到一个解决方案,允许我打开选择元素,而不关闭下拉菜单。我将非常感谢任何关于如何实现这一目标的见解或建议。
下面是相关的HTML代码(html文件代码)供参考。谢谢您的帮助!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
rel="stylesheet"
id="hello-elementor-child-style-css"
href="https://fs.codelinden.com/wp-content/themes/hello-child/style.css?ver=3"
media="all"
/>
<link rel="stylesheet" href="header.css" />
<script src="header.js" defer></script>
<!-- single-menu dropdown style -->
<link rel="stylesheet" href="single-menu-dropdown.css" />
<!-- custom form element style (nice-select) -->
<link rel="stylesheet" href="form.css" />
<!-- nice-select style-->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/jquery-nice-select/1.1.0/css/nice-select.min.css"
integrity="sha512-CruCP+TD3yXzlvvijET8wV5WxxEh5H8P4cmz0RFbKK6FlZ2sYl3AEsKlLPHbniXKSrDdFewhbmBK5skbdsASbQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<title>Header</title>
</head>
<body>
<header class="header HruDj">
<div class="nav-dropdown target-id DeYlt" id="target_id1">
<p>toggle dropdown</p>
<!-- single-menu dropdown container -->
<div id="menu_id1" class="menu-id">
<div class="form-field full-width">
<input
type="hidden"
name="form_my_contact_form"
value="1"
/>
<label for="product_type">Product Type</label>
<select
name="product_type"
id="product_type"
required=""
>
<option value="book">Book</option>
<option value="movie">Movie</option>
<option value="music">Music</option>
<option value="" disabled="">
Select a product type
</option>
</select>
</div>
</div>
</div>
<div class="nav-dropdown target-id DeYlt" id="target_id2">
<p>toggle dropdown</p>
<!-- single-menu dropdown container -->
<div id="menu_id2" class="menu-id">
<div class="form-field full-width">
<input
type="hidden"
name="form_my_contact_form"
value="1"
/>
<label for="product_type">Product Type</label>
<select
name="product_type"
id="product_type"
required=""
>
<option value="book">Book</option>
<option value="movie">Movie</option>
<option value="music">Music</option>
<option value="" disabled="">
Select a product type
</option>
</select>
</div>
</div>
</div>
</div>
</header>
<!-- jquery cdn -->
<script src="popup/jquery/jquery.min.js"></script>
<!-- single-menu dropdown script -->
<script src="single-menu-dropdown.js"></script>
<!-- nice-select script -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery-nice-select/1.1.0/js/jquery.nice-select.min.js"
integrity="sha512-NqYds8su6jivy1/WLoW8x1tZMRD7/1ZfhWG/jcRQLOzV1k1rIODCpMgoBnar5QXshKJGV7vi0LXLNXPoFsM5Zg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<!-- initialize dropdown and select -->
<script>
// Call singleMenu function for each menu
singleMenu("target_id1", "menu_id1", false);
singleMenu("target_id2", "menu_id2", false);
$(document).ready(function () {
// Apply the niceSelect plugin to all select elements
$("select").niceSelect();
});
</script>
</body>
</html>
型
3条答案
按热度按时间hkmswyz61#
所以我能够达到预期的结果,但有一些小的变化。对于
event.stopPropagation()
,似乎没有任何方法可以一致地工作。您可以做的是,不要将整个菜单父级设置为单击处理程序,而是将其设置为在更直接的目标上工作。
这意味着,如果不使用
字符串
您可能希望将目标ID添加到内部的p标记中。
型
menu_id2和target_id2也是如此。
这将需要在JavaScript中做一个小的更改。将单击外部时关闭菜单的单击处理程序更改为处理
targetElement.parentElement
,以说明目标现在位于菜单内。型
去掉菜单停止传播项,因为不再需要它。
型
总而言之,下面是您的问题中更新的代码,它应该按预期工作。
的字符串
注意:将以下代码移动到JavaScript部分只是为了使代码片段可运行,这不是必需的修改。
型
hfyxw5xn2#
我很确定这只是因为事件传播顺序而发生的。当点击
select
时,这就是我看到的情况:select
上的click事件触发niceSelect
函数。1.然后click事件冒泡到父元素,最终到达
menuElement
,并在添加event.stopPropagation()
后停止。我认为这是一个问题的原因是因为
niceSelect
在单击时不会立即解析,它在执行其操作之前等待下一个事件循环。但是由于事件在此之前就已经命中了stopPropagation()
,因此stopPropagation()
阻止了此事件的发生。解决这个问题的一个可能的非正统方法是延迟您在
stopPropagation()
上的止损,如下所示:字符串
通俗地说,这告诉JavaScript “在事件循环结束后,但在下一个循环开始之前,立即运行此代码”。
eqqqjvef3#
在将事件侦听器添加到
targetElement
时,尝试通过提供第三个属性true
将useCapture
指定为true
。所以它在menuElement
的click事件之前触发:字符串