jQuery .focusout / .click 冲突

IT技术 javascript jquery
2021-03-09 01:53:18

我正在处理一个带有自动完成搜索框的项目。现在我有一个问题,我想将找到的自动完成结果中的值传递给输入框,但同时,我希望自动完成框在输入字段不是更集中时隐藏。

现在我和他们两个都发生了冲突,因为点击自动完成框被视为焦点,甚至在它可以传递值之前隐藏框。此类问题的任何指示或解决方法?这里有一个 jsfiddle 让你更清楚。

http://jsfiddle.net/KeGvM/

或者这里

CSS :

#a_c {display:none;}​

JS

$('#search_field').focusout(function() {
    $('#a_c').hide(); // IF I DELETE THIS IT WORKS
});

$('#search_field').focusin(function() {
    $('#a_c').show();
});

$('#a_c a').click(function() {
    $('#search_field').val('');
    var value = $(this).text();
    var input = $('#search_field');
    input.val(input.val() + value);
    $('#a_c').hide();
    return false;
});​

HTML :

<input autocomplete="off" onkeyup="searchFor(this.value);" name="search" id="search_field" class="bold" type="text" placeholder="Search...">
<div id="a_c"><a href="">hello world</a></div>​
3个回答

我解决这个问题的方法是使用mousedown事件而不是click. mousedown是事件总是前触发的focusout事件,而click不是。

您可以在下面的小演示中尝试一下。专注于该字段,然后单击按钮。

const field = document.getElementById('field');
const btn = document.getElementById('btn');

btn.addEventListener('click', () => console.log('Click'));
btn.addEventListener('mousedown', () => console.log('Mouse down'));
field.addEventListener('focusout', () => console.log('Focus out'));
<input id="field">
<button id="btn">Try it</button>

如您所见,输出顺序如下:

  1. 鼠标按下
  2. 专注
  3. 点击

这是最稳定的解决方案,无需使用超时等任何变通方法。它也不依赖于 jQuery。唯一值得注意的是mousedown不会等待用户释放鼠标按钮,但就用户体验而言,这并不是真正的问题。

这应该是公认的答案,感谢您的调查!
2021-04-21 01:53:18
有史以来最好的解决方案!太感谢了!
2021-05-12 01:53:18

怎么用

:徘徊

我用它解决了同样的问题。

$('className').on('focusout', function(e) {
    if($('.suggestLi' + ':hover').length) {
        return;
    }
    $('.suggestList').empty();
});
如果鼠标悬停建议列表,则不起作用,我将按 TAB(如移动到下一个输入)(而不是单击)JSFIDDLE
2021-04-21 01:53:18
我认为这是最好的解决方案。我已经使用了它,它完美地工作。谢谢!
2021-04-25 01:53:18
这是我在互联网上找到的最优雅的解决方案。谢谢。
2021-05-21 01:53:18

我在类似情况下的解决方案是使用超时来暂时推迟在blur事件处理程序中采取的行动像这样:

$('#search_field').focusout(function() {
    window.setTimeout(function() { $('#a_c').hide() }, 100);
});
@raina77ow,我明白你的意思,我需要在验证前后检查数据更新,以便我可以跳过它?但我所做的是.. 在验证时我添加了inputDomElement.focus(). 当窗口被交换时,它触发了弹出验证的循环。现在我删除focus并解决了这个问题。
2021-04-26 01:53:18
这是一个很棒的解决方案.. +1。我正在验证 - 使用 txtEmailfield focusout 事件的电子邮件是否有效。如果在光标聚焦的情况下输入无效电子邮件,请立即单击表单清除按钮。这导致了冲突。现在我用你的超时而不是空白条件覆盖了代码。谢谢
2021-04-27 01:53:18
我有一个类似 op 的问题,我决定使用这个肮脏的修复作为解决方案(最后的手段,我必须在截止日期前尽快解决这个问题)。这使事件处于竞争状态,这是一种非常非常糟糕的做法。我会用这个,谢谢你的回答,但会否决。等待更好的答案。
2021-05-05 01:53:18
@raina77ow,我面临一个不同的焦点验证代码问题,如果验证是通过弹出窗口触发的,单击确定按钮关闭弹出按钮。如果使用交换窗口Alt+Tab并将其交换回应用程序窗口,则弹出窗口将继续出现。如何解决这个问题?
2021-05-11 01:53:18
@PraneshJanarthanan 视情况而定。例如,您可能希望限制给定输入的弹出窗口显示次数(即,如果自上次显示弹出窗口以来没有任何变化,为什么要显示它?) 不过,请考虑用户到达的状态:如果他们在长时间不活动后切换回那个窗口,他们是否总是记得到底应该做什么?
2021-05-11 01:53:18