如何在多个元素上设置焦点但防止在它们之间转移焦点时?

发布于 2025-01-11 11:18:48 字数 1143 浏览 0 评论 0原文

我想创建一个可搜索的输入,当它获得焦点时,会显示一个下拉列表,其中包含使用服务器端语言填充的可能值列表。我尝试在不属于使用以下代码涉及的元素之一的任何元素上使用 focusin

$("body").not($(".dropdownSearch").find("input")).not($(".dropdownSearch").find("a")).on("click focusin", function () {
    $(".dropdown-menu").hide();
});

但是当我运行代码并单击输入时,它实际上得到了 focusin输入,但之后在正文上获得 focusin 并在输入时发生 focusout

这是 html 元素:

<div class="dropdownSearch dropdown">

    <span><input type="text" id="input1" name="input1" class="dropdown-toggle" /></span>
    <span><input type="text" id="input2" name="input2" class="dropdown-toggle" /></span>
    <span><input type="text" id="input3" name="input3" class="dropdown-toggle" /></span>

    <div class="dropdown-menu">
        <a class="dropdown-item">name</a>
        <a class="dropdown-item">name</a>
        <a class="dropdown-item">name</a>
    </div>

</div>

在此代码中,多个输入可以打开相同的下拉列表,但使用 js 从 JSON 文件读取数据来更改值。

还有更好的办法吗?感谢您的任何帮助。

I want to make a searchable input that when it gets focusin shows a dropdown containing list of possible values that fills using server side language. I tried to use focusin on any element that is not one of elements that are involved using code below:

$("body").not($(".dropdownSearch").find("input")).not($(".dropdownSearch").find("a")).on("click focusin", function () {
    $(".dropdown-menu").hide();
});

But when I run the code and click on input it actually get focusin on input but after that get focusin on body and focusout occur on input.

And this is html elements:

<div class="dropdownSearch dropdown">

    <span><input type="text" id="input1" name="input1" class="dropdown-toggle" /></span>
    <span><input type="text" id="input2" name="input2" class="dropdown-toggle" /></span>
    <span><input type="text" id="input3" name="input3" class="dropdown-toggle" /></span>

    <div class="dropdown-menu">
        <a class="dropdown-item">name</a>
        <a class="dropdown-item">name</a>
        <a class="dropdown-item">name</a>
    </div>

</div>

In this code multiple inputs can open same dropdown but change the values using js reads data from JSON files.

Is there any better way? Thanks for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拔了角的鹿 2025-01-18 11:18:48

因此,让我们稍微解压一下您的选择器,因为我不确定它正在执行您想要执行的操作

您可以简化此 $(".dropdownSearch").find("input") ,它会查找任何 input 元素作为 .dropdownSearch 的后代到单个 CSS 后代选择器,如 $(".dropdownSearch input")

所以你的选择器与此相同:

$("body").not(".dropdownSearch input").not(".dropdownSearch a")

它正在寻找任何 body 元素,但如果它是 inputa,它有效地解析为仅选择正文:

$("body")

它将侦听发生的所有事件和气泡一直到正文,无论他们的起源。


我认为你想要的是一个 委托处理程序 来监听冒泡的事件body,但只有在它们与提供的选择器匹配时才继续,或者您可以像这样检查处理程序内的值:

$("body").on("click focus", function (e) {
  var notDropdownEl = $(e.target).is(":not(.dropdownSearch input):not(.dropdownSearch a)")

  if (notDropdownEl) {
    $(".dropdown-menu").hide();
  }
});

我不太确定您在寻找什么,但这里有一个将隐藏的堆栈片段单击外部时的下拉菜单 dropdowsearch 区域

Stack Snippets 中的

演示

$("body").on("click focus", function (e) {
  if ($(e.target).is(":not(.dropdownSearch input):not(.dropdownSearch a)")) {
    $(".dropdown-menu").hide();
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<div class="dropdownSearch dropdown">
    Will Not Hide if Clicked here
    <span><input type="text" id="input1" name="input1" class="dropdown-toggle" /></span>
    <span><input type="text" id="input2" name="input2" class="dropdown-toggle" /></span>
    <span><input type="text" id="input3" name="input3" class="dropdown-toggle" /></span>

    <div class="dropdown-menu">
        <a class="dropdown-item">name</a>
        <a class="dropdown-item">name</a>
        <a class="dropdown-item">name</a>
    </div>

</div>

<p>Will Hide if Clicked Here</p>
<input type="text" name="outside" />

So let's unpack your selector a little, because I'm not sure it's doing what you intend it to do

You can simplify this $(".dropdownSearch").find("input") which looks for any input elements as the descendants of .dropdownSearch to a single CSS descendant selector like this $(".dropdownSearch input").

So you're selector is identical to this:

$("body").not(".dropdownSearch input").not(".dropdownSearch a")

What this is looking for is any body element, but then exclude that match if it's an input or a, which effectively resolve to just selecting the body:

$("body")

Which will listen for all events that happen and bubble all the way up to body, regardless of their origin.


What I think you want is a delegated handler to listen for events that bubble up to body, but then only proceed if they match the provided selector or you can check the value inside the handler like this:

$("body").on("click focus", function (e) {
  var notDropdownEl = $(e.target).is(":not(.dropdownSearch input):not(.dropdownSearch a)")

  if (notDropdownEl) {
    $(".dropdown-menu").hide();
  }
});

I'm not quite positive what your looking for, but here's a stack snippet that will hide the dropdown when you click outside of the dropdowsearch area

Demo in Stack Snippets

$("body").on("click focus", function (e) {
  if ($(e.target).is(":not(.dropdownSearch input):not(.dropdownSearch a)")) {
    $(".dropdown-menu").hide();
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<div class="dropdownSearch dropdown">
    Will Not Hide if Clicked here
    <span><input type="text" id="input1" name="input1" class="dropdown-toggle" /></span>
    <span><input type="text" id="input2" name="input2" class="dropdown-toggle" /></span>
    <span><input type="text" id="input3" name="input3" class="dropdown-toggle" /></span>

    <div class="dropdown-menu">
        <a class="dropdown-item">name</a>
        <a class="dropdown-item">name</a>
        <a class="dropdown-item">name</a>
    </div>

</div>

<p>Will Hide if Clicked Here</p>
<input type="text" name="outside" />

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文