我创建了一个自定义下拉菜单,并希望获取其中被单击元素的文本内容。
Dropdown元素是与事件侦听器一样动态创建的,但是侦听器似乎无法正常工作。
下拉示例:
我可以在开发工具中看到每个div上的侦听器。
子div的事件监听器:
下拉菜单中的第一个div会用输入的值填充输入值,而其他输入则不会。
(function() {
let departments = ['Accounting', 'Human Resources', 'IT', 'Warehouse'];
let element = document.getElementById('dd-Department');
departments.forEach(v => {
let div = document.createElement('div');
div.appendChild(document.createTextNode(v));
div.addEventListener('click', () => {
element.parentNode.querySelector('input').value = v;
});
element.appendChild(div);
});
})();
.form-question {
display: flex;
flex-direction: column;
justify-content: center;
margin: 0 0 3rem;
min-height: 3rem;
}
.form-question__title {
color: #342357;
font-size: 1.5rem;
padding: 1rem;
}
.input-container {
border-bottom: solid 2px #333333;
position: relative;
}
input[readonly] {
cursor: pointer;
}
.input-container input {
border: none;
box-sizing: border-box;
outline: 0;
padding: .75rem;
position: relative;
width: 100%;
}
.input-container:focus-within .dropdown {
transform: scaleY(1);
}
.dropdown {
background: #ffffff;
box-shadow: 0 5px 12px #333333;
left: 0;
max-height: 300px;
overflow-y: auto;
padding: 0;
position: absolute;
right: 0;
top: calc(100% + 2px);
transform: scaleY(0);
transform-origin: top;
transition: transform .3s;
z-index: 10;
}
.dropdown div {
border-bottom: 2px solid #777777;
cursor: pointer;
padding: 8px;
z-index: 20;
}
.dropdown div:hover {
background: #dddddd;
font-weight: 800;
}
<div class="form-question">
<div class="form-question__title">
<span>Department</span>
</div>
<div class="form-question--dropdown input-container">
<input type="text" name="Department" readonly="readonly"></input>
<div id="dd-Department" class="dropdown"></div>
</div>
</div>
我也尝试了事件委派,但是无法获得单击的div的文本内容。目标是目标div的父级,因此文本内容是所有子级值的组合。
let element = document.getElementById('dd-Department');
element.addEventListener('click', e => {
if (e.target && e.target.classList.contains('dropdown')) {
e.target.parentNode.parentNode.querySelector('input').value = e.target.textContent;
}
}, true);
点击子div时的事件委派:
我在这里想念东西吗?
更新
感谢@dawn指出css是问题所在。 我已经通过更改来解决此问题
.input-container:focus-within .dropdown
到
.input-container.active .dropdown
并使用javascript添加活动类。
document.querySelectorAll('.input-container').forEach(v => {
v.onclick = () => v.classList.toggle('active');
});
现在的问题是,在单击除输入容器之外的任何内容时,下拉列表仍处于活动状态。
以下内容有效,但感觉像是黑客。
document.querySelectorAll('.input-container').forEach(v => {
v.addEventListener('focus', () => v.classList.add('active'), true);
v.addEventListener('blur', () => setTimeout(() => v.classList.remove('active'), 75), true);
});
还有更优雅的解决方案吗?
答案 0 :(得分:1)
这种情况是CSS的问题,当您单击div时,触发的第一件事是“ transform:scaleY(0)”,并且“ .dropdown”不可见,因此无法触发click事件。
请勿使用input:focus-within来控制下拉框的可见性,因为当您单击下拉框时,输入失去了焦点。