单击按钮不起作用后,将焦点返回到输入



这必须非常简单,但我只是没有找到任何答案。我有一个简单的菜单,可以在搜索文本框中输入特殊字符。它在做它的工作,但如果我点击一个字符,菜单会(模糊(,焦点不会返回到字段。只要光标在字段中和/或我单击字符菜单,我就希望菜单保持可见。在菜单按钮的事件列表中,第一行和最后一行有效。文本被附加到搜索框中,helloworld被记录到控制台中。但菜单不会显示,文本框也不会重新获得焦点。这里怎么了?

的问题演示

let searchInput = document.querySelector('#search-input');
let charsMenu = document.querySelector('.charsmenu');
// add event listeners to textbox                                                                                                                                             
searchInput.addEventListener('focus', function() {
toggleDisplay(charsMenu, true);
});
searchInput.addEventListener('blur', function() {
toggleDisplay(charsMenu, false);
});
function toggleDisplay(element, show) {
if (show)
element.style.display = 'block';
else
element.style.display = 'none';
}
let listItems = document.querySelectorAll('.charsmenu li');
listItems.forEach((item, index) => {
item.addEventListener('mousedown', (event) => {
searchInput.value += `${event.currentTarget.innerHTML}`;
toggleDisplay(charsMenu, true);
searchInput.focus();
console.log("Hello world!");
});
});

触发mousedown后,<li>元素很可能会将焦点从输入元素上移开。因此,您需要推迟将焦点设置在调用堆栈末尾的输入元素上,即:

window.setTimeout(() => searchInput.focus(), 0);

见以下概念验证:

let searchInput = document.querySelector('#search-input');
let charsMenu = document.querySelector('.charsmenu');
// add event listeners to textbox                                                                                                                                             
searchInput.addEventListener('focus', function() {
toggleDisplay(charsMenu, true);
});
searchInput.addEventListener('blur', function() {
toggleDisplay(charsMenu, false);
});
function toggleDisplay(element, show) {
if (show)
element.style.display = 'block';
else
element.style.display = 'none';
}
let listItems = document.querySelectorAll('.charsmenu li');
listItems.forEach((item, index) => {
item.addEventListener('mousedown', (event) => {
searchInput.value += `${event.currentTarget.innerHTML}`;
toggleDisplay(charsMenu, true);
window.setTimeout(() => searchInput.focus(), 0);
});
});
.wrapper {
display: flex;
}
.charsmenu {
display: none;
list-style: none;
}
.charsmenu li {
float: left;
border: 1px solid black;
padding: 16px;
}
<div class="wrapper">
<ul class="charsmenu">
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
<input type="text" id="search-input" />
</div>

正如Terry所说,焦点无论如何都被偷走了
我的解决方案只是在焦点设置之前添加preventDefault()

listItems.forEach((item, index) => {
item.addEventListener('mousedown', (event) => {
searchInput.value += `${event.currentTarget.innerHTML}`;
toggleDisplay(charsMenu, true);
event.preventDefault();
searchInput.focus();
});
});

顺便说一下,您可以在一个<UL>而不是每个<LI>上设置事件侦听器。

最新更新