如何解决如何有效地管理多个自定义下拉 DOM 元素的行为和可见性状态?
document.querySelectorAll('.selector').forEach((item) => {
item.addEventListener("click",(event) => {
document.querySelectorAll('.dropdown').classList.add("active");
});
});
.body-ct .selector{display:inline-block;width:200px;text-align:center;border:1px solid navy;border-radius:4px;}
.body-ct .selector:hover{cursor:pointer;}
.body-ct .selector h4{padding:5px 0;}
.body-ct .selector {position:relative;}
.body-ct .selector .dropdown{display:none;position:absolute;top:55px;z-index:2;width:200px;border:3px solid red;background-color:#FFF;}
.body-ct .selector .dropdown.active{display:block;}
.body-ct .selector .dropdown ul{list-style-type:none;text-align:left;background-color:#FFF;}
.body-ct .selector .dropdown ul li{background-color:#FFF;}
.body-ct .selector .dropdown ul li:hover{font-weight:700;}
<section class="body-ct">
<div class="container">
<div class="row">
<div class="col-12 sel-ct">
<div class="story-type-sel selector">
<h4>Story Type</h4>
<div class="dropdown story-selector">
<ul>
<li data-type="article">Article</li>
<li data-type="pr">Press Release</li>
<li data-type="analyst">Analyst Report</li>
</ul>
</div>
</div>
<div class="year-sel selector">
<h4>Year</h4>
<div class="dropdown year-selector">
<ul>
<li data-year="2021">2021</li>
<li data-year="2020">2020</li>
<li data-year="2019">2019</li>
<li data-year="2018">2018</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
我无法从我的事件侦听器中引用 dropdown
类。我认为这与使用 .target
或 .currentTarget
有关,但我不确定如何将它们组合在一起。
当用户单击带有 .selector
的元素时,应通过添加 .active
类来显示下拉菜单。
document.querySelectorAll(".selector").forEach((item) => {
item.addEventListener("click",(event) => {
document.querySelector(".dropdown").classList.add("active");
});
});
在 jQuery 中也有同样的事情,但我不想使用 jQuery。
$(".selector").on("click",function () {
$(this).find(".dropdown").addClass("active");
});
解决方法
问题是 document.querySelectorAll()
返回代码中所有 dropdown
元素的数组,而 document.querySelector()
返回他找到的第一个元素,但不需要元素内的元素触发事件。
如果您想将 active
类添加到包含在被点击的 selector
元素中的下拉元素中,您可以从事件当前目标而不是从 {{ 1}}:
querySelector()
,
querySelectorAll 返回一个节点列表。使用 forEach。
document.querySelectorAll('.selector').forEach((item) => {
item.addEventListener("click",(event) => {
event.target.querySelectorAll(".dropdown").forEach((dopdownItem) => {
dopdownItem.classList.add("active");
});
});
});
.body-ct .selector {
display: inline-block;
width: 200px;
text-align: center;
border: 1px solid navy;
border-radius: 4px;
}
.body-ct .selector:hover {
cursor: pointer;
}
.body-ct .selector h4 {
padding: 5px 0;
}
.body-ct .selector {
position: relative;
}
.body-ct .selector .dropdown {
display: none;
position: absolute;
top: 55px;
z-index: 2;
width: 200px;
border: 3px solid red;
background-color: #FFF;
}
.body-ct .selector .dropdown.active {
display: block;
}
.body-ct .selector .dropdown ul {
list-style-type: none;
text-align: left;
background-color: #FFF;
}
.body-ct .selector .dropdown ul li {
background-color: #FFF;
}
.body-ct .selector .dropdown ul li:hover {
font-weight: 700;
}
<section class="body-ct">
<div class="container">
<div class="row">
<div class="col-12 sel-ct">
<div class="story-type-sel selector">
<h4>Story Type</h4>
<div class="dropdown story-selector">
<ul>
<li data-type="article">Article</li>
<li data-type="pr">Press Release</li>
<li data-type="analyst">Analyst Report</li>
</ul>
</div>
</div>
<div class="year-sel selector">
<h4>Year</h4>
<div class="dropdown year-selector">
<ul>
<li data-year="2021">2021</li>
<li data-year="2020">2020</li>
<li data-year="2019">2019</li>
<li data-year="2018">2018</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
一种天真的/基本事件和状态/外观处理方法可能看起来像下一个......
function deactivateDropdown(elm) {
elm.classList.remove('active');
}
function activateDropdown(elm) {
elm.classList.add('active');
}
function deactivateAnyDropdown() {
document
.querySelectorAll('.dropdown')
.forEach(deactivateDropdown);
}
function handleSelectorClick(evt) {
evt.stopPropagation();
deactivateAnyDropdown();
activateDropdown(
evt
.currentTarget
.querySelector('.dropdown')
);
}
function init() {
document
.body
.addEventListener('click',deactivateAnyDropdown)
document
.querySelectorAll('.selector')
.forEach(item =>
item.addEventListener('click',handleSelectorClick)
);
}
init();
.body-ct .selector{display:inline-block;width:200px;text-align:center;border:1px solid navy;border-radius:4px;}
.body-ct .selector:hover{cursor:pointer;}
.body-ct .selector h4{padding:5px 0;}
.body-ct .selector {position:relative;}
.body-ct .selector .dropdown{display:none;position:absolute;top:55px;z-index:2;width:200px;border:3px solid red;background-color:#FFF;}
.body-ct .selector .dropdown.active{display:block;}
.body-ct .selector .dropdown ul{list-style-type:none;text-align:left;background-color:#FFF;}
.body-ct .selector .dropdown ul li{background-color:#FFF;}
.body-ct .selector .dropdown ul li:hover{font-weight:700;}
<section class="body-ct">
<div class="container">
<div class="row">
<div class="col-12 sel-ct">
<div class="story-type-sel selector">
<h4>Story Type</h4>
<div class="dropdown story-selector">
<ul>
<li data-type="article">Article</li>
<li data-type="pr">Press Release</li>
<li data-type="analyst">Analyst Report</li>
</ul>
</div>
</div>
<div class="year-sel selector">
<h4>Year</h4>
<div class="dropdown year-selector">
<ul>
<li data-year="2021">2021</li>
<li data-year="2020">2020</li>
<li data-year="2019">2019</li>
<li data-year="2018">2018</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
...它为停用当前未使用/点击的下拉菜单提供基本支持。
但上述行为,出于原因,远非理想。因此,更高级的方法将只关注单个元素,在这种情况下,它是 OP 分类为 .selector
的下拉列表的触发器。
人们希望 active
-class 也成为该元素的一部分,而不是 add
ing 和/或 remove
ing 这个 class 而是 toggle
它。
其中一个原因需要相应地更改相关切换行为的 css-selector。
上面的示例代码然后变成了下面的...
function deactivateDropdown(elm) {
elm.classList.remove('active');
}
function toggleDropdown(elm) {
elm.classList.toggle('active');
}
function deactivateAnyNonActiveDropdown(evt) {
const { currentTarget,target } = evt;
Array
.from(
document.querySelectorAll('.selector')
)
.filter(elm =>
elm !== currentTarget ||
elm
.querySelector('.dropdown')
.contains(target)
)
.forEach(deactivateDropdown);
}
function handleSelectorClick(evt) {
evt.stopPropagation();
deactivateAnyNonActiveDropdown(evt);
toggleDropdown(evt.currentTarget);
}
function init() {
document
.body
.addEventListener('click',deactivateAnyNonActiveDropdown)
document
.querySelectorAll('.selector')
.forEach(item =>
item.addEventListener('click',handleSelectorClick)
);
}
init();
.body-ct .selector{display:inline-block;width:200px;text-align:center;border:1px solid navy;border-radius:4px;}
.body-ct .selector:hover{cursor:pointer;}
.body-ct .selector h4{padding:5px 0;}
.body-ct .selector {position:relative;}
.body-ct .selector .dropdown{display:none;position:absolute;top:55px;z-index:2;width:200px;border:3px solid red;background-color:#FFF;}
/*.body-ct .selector .dropdown.active{display:block;}*/
.body-ct .selector.active .dropdown {display:block;}
.body-ct .selector .dropdown ul{list-style-type:none;text-align:left;background-color:#FFF;}
.body-ct .selector .dropdown ul li{background-color:#FFF;}
.body-ct .selector .dropdown ul li:hover{font-weight:700;}
<section class="body-ct">
<div class="container">
<div class="row">
<div class="col-12 sel-ct">
<div class="story-type-sel selector">
<h4>Story Type</h4>
<div class="dropdown story-selector">
<ul>
<li data-type="article">Article</li>
<li data-type="pr">Press Release</li>
<li data-type="analyst">Analyst Report</li>
</ul>
</div>
</div>
<div class="year-sel selector">
<h4>Year</h4>
<div class="dropdown year-selector">
<ul>
<li data-year="2021">2021</li>
<li data-year="2020">2020</li>
<li data-year="2019">2019</li>
<li data-year="2018">2018</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。